瀏覽代碼

添加规格分类

panhui 5 年之前
父節點
當前提交
7a68ddaacb
共有 7 個文件被更改,包括 1204 次插入1109 次删除
  1. 13 11
      Redux/RefreashRedux.js
  2. 8 0
      components/ListComponent.js
  3. 184 169
      models/goodsModel.js
  4. 242 251
      screens/FullReduction.js
  5. 390 290
      screens/Goods/GoodsSpecificationScreen.js
  6. 365 386
      screens/Guide1Screen.js
  7. 2 2
      screens/Set/OrderSetting.js

+ 13 - 11
Redux/RefreashRedux.js

@@ -1,15 +1,17 @@
-//下拉刷新,获取更多数据处理
+// 下拉刷新,获取更多数据处理
 export const initState = {
 export const initState = {
-    refreshing: false,
-    error: false,
+  refreshing: false,
+  error: false,
 };
 };
 export function refreashReducer(state, action) {
 export function refreashReducer(state, action) {
-    switch (action.type) {
-        case "startRefresh":
-            return { refreshing: true, error: false };
-        case "refreshFinish":
-            return { refreshing: false, error: false };
-        case "refreshError":
-            return { refreshing: false, error: true };
-    }
+  switch (action.type) {
+    case "startRefresh":
+      return { refreshing: true, error: false };
+    case "refreshFinish":
+      return { refreshing: false, error: false };
+    case "refreshError":
+      return { refreshing: false, error: true };
+    default:
+      return state;
+  }
 }
 }

+ 8 - 0
components/ListComponent.js

@@ -4,10 +4,12 @@
 import React from "react";
 import React from "react";
 import { Divider, List, Layout } from "@ui-kitten/components";
 import { Divider, List, Layout } from "@ui-kitten/components";
 import { useFocusEffect } from "@react-navigation/native";
 import { useFocusEffect } from "@react-navigation/native";
+import { useModel } from "flooks";
 import { initDataState, DataListReducer } from "../Redux/DataListRedux";
 import { initDataState, DataListReducer } from "../Redux/DataListRedux";
 import EmptyComponent from "./EmptyComponent";
 import EmptyComponent from "./EmptyComponent";
 
 
 export default function ListComponent(props) {
 export default function ListComponent(props) {
+  const { clearLoading } = useModel("loadingModel");
   const [state, dispatch] = React.useReducer(DataListReducer, initDataState);
   const [state, dispatch] = React.useReducer(DataListReducer, initDataState);
   const { page, size, loading, refreshing, dataList } = state;
   const { page, size, loading, refreshing, dataList } = state;
   const {
   const {
@@ -75,6 +77,9 @@ export default function ListComponent(props) {
           type: "refreshError",
           type: "refreshError",
           payload: { error: e.message },
           payload: { error: e.message },
         });
         });
+      })
+      .finally(() => {
+        clearLoading();
       });
       });
   }
   }
 
 
@@ -90,6 +95,9 @@ export default function ListComponent(props) {
           type: "pageMoreError",
           type: "pageMoreError",
           payload: { error: e.message },
           payload: { error: e.message },
         });
         });
+      })
+      .finally(() => {
+        clearLoading();
       });
       });
   }
   }
 
 

+ 184 - 169
models/goodsModel.js

@@ -1,184 +1,199 @@
+/* eslint-disable no-underscore-dangle */
 import ListUtil from "../Utils/ListUtil";
 import ListUtil from "../Utils/ListUtil";
 
 
 export default {
 export default {
-    state: {
-        selectInfos: [],
-        Classifications: [], // 商户分类列表
-        classificationId: 0, // 当前操作的商品分类
+  state: {
+    selectInfos: [],
+    Classifications: [], // 商户分类列表
+    classificationId: 0, // 当前操作的商品分类
+  },
+  actions: ({ model, setState }) => ({
+    // 商家分类选择商品
+    changeSelect(list) {
+      setState({
+        selectInfos: list,
+      });
     },
     },
-    actions: ({ model, setState }) => ({
-        // 商家分类选择商品
-        changeSelect(list) {
-            setState({
-                selectInfos: list,
-            });
-        },
-        // 下架提示
-        takeOffInfo(callBack) {
-            const { showDialog } = model("dialogModel");
-            const { takeOffTips } = model("wordsModel");
-            showDialog({
-                bodyText: takeOffTips,
-                status: "danger",
-                cancelable: true,
-                confirmCallback: () => callBack(),
-            });
-        },
-        // 商品上下架
-        ChangeTakeOff(info) {
-            const { id } = info;
-            const { getWordsStr, successText } = model("wordsModel");
-            const { httpGet } = model("httpModel");
-            const { success } = model("loadingModel");
+    // 下架提示
+    takeOffInfo(callBack) {
+      const { showDialog } = model("dialogModel");
+      const { takeOffTips } = model("wordsModel");
+      showDialog({
+        bodyText: takeOffTips,
+        status: "danger",
+        cancelable: true,
+        confirmCallback: () => callBack(),
+      });
+    },
+    // 商品上下架
+    ChangeTakeOff(info) {
+      const { id } = info;
+      const { getWordsStr, successText } = model("wordsModel");
+      const { httpGet } = model("httpModel");
+      const { success } = model("loadingModel");
 
 
-            return httpGet(
-                "/goods/take",
-                {
-                    id,
-                },
-                true
-            )
-                .then(() => {
-                    return httpGet(`/goods/get/${  id}`, {}, true);
-                })
-                .then(res => {
-                    success(
-                        getWordsStr(res.takeOff ? "takeOff" : "takeUp") +
-                            successText
-                    );
-                    return Promise.resolve(res);
-                });
-        },
-        // 关闭分类提示
-        clossClassTip(callBack) {
-            const { showDialog } = model("dialogModel");
-            const { systemClassTips1 } = model("wordsModel");
-            showDialog({
-                bodyText: systemClassTips1,
-                status: "danger",
-                cancelable: true,
-                confirmCallback: () => callBack(),
-            });
-        },
-        saveInfo(info, noTip) {
-            const { saveSuccess, editSuccess } = model("wordsModel");
-            const { httpPost } = model("httpModel");
-            const { success } = model("loadingModel");
-            return httpPost(
-                "/classification/save",
-                info,
-                { body: "json" },
-                true
-            ).then(res => {
-                if (!noTip) {
-                    success(info.id ? editSuccess : saveSuccess);
-                }
-                return Promise.resolve(res);
-            });
+      return httpGet(
+        "/goods/take",
+        {
+          id,
         },
         },
-        // 移除分类商品
-        removeClassGoods(classificationId, goodId, callBack) {
-            const { showDialog } = model("dialogModel");
-            const { removeTips, editSuccess } = model("wordsModel");
-            const { httpGet } = model("httpModel");
-            const { success } = model("loadingModel");
-            showDialog({
-                bodyText: removeTips,
-                status: "danger",
-                cancelable: true,
-                confirmCallback: () => {
-                    httpGet(
-                        "/classification/delGoods",
-                        {
-                            classificationId,
-                            goodId,
-                        },
-                        true
-                    ).then(res => {
-                        success(editSuccess);
-                        callBack(res);
-                    });
-                },
-            });
+        true
+      )
+        .then(() => {
+          return httpGet(`/goods/get/${id}`, {}, true);
+        })
+        .then(res => {
+          success(
+            getWordsStr(res.takeOff ? "takeOff" : "takeUp") + successText
+          );
+          return Promise.resolve(res);
+        });
+    },
+    // 关闭分类提示
+    clossClassTip(callBack) {
+      const { showDialog } = model("dialogModel");
+      const { systemClassTips1 } = model("wordsModel");
+      showDialog({
+        bodyText: systemClassTips1,
+        status: "danger",
+        cancelable: true,
+        confirmCallback: () => callBack(),
+      });
+    },
+    saveInfo(info, noTip) {
+      const { saveSuccess, editSuccess } = model("wordsModel");
+      const { httpPost } = model("httpModel");
+      const { success } = model("loadingModel");
+      return httpPost(
+        "/classification/save",
+        info,
+        { body: "json" },
+        true
+      ).then(res => {
+        if (!noTip) {
+          success(info.id ? editSuccess : saveSuccess);
+        }
+        return Promise.resolve(res);
+      });
+    },
+    // 移除分类商品
+    removeClassGoods(classificationId, goodId, callBack) {
+      const { showDialog } = model("dialogModel");
+      const { removeTips, editSuccess } = model("wordsModel");
+      const { httpGet } = model("httpModel");
+      const { success } = model("loadingModel");
+      showDialog({
+        bodyText: removeTips,
+        status: "danger",
+        cancelable: true,
+        confirmCallback: () => {
+          httpGet(
+            "/classification/delGoods",
+            {
+              classificationId,
+              goodId,
+            },
+            true
+          ).then(res => {
+            success(editSuccess);
+            callBack(res);
+          });
         },
         },
-        // 添加分类商品
-        addClassGoods(info) {
-            const { successText } = model("wordsModel");
-            const { success } = model("loadingModel");
-            const { httpPost } = model("httpModel");
-            return httpPost(
-                "/goodsSpecification/save",
-                info,
-                {
-                    body: "json",
-                },
-                true
-            ).then(res => {
-                success(successText);
-                return Promise.resolve(res);
-            });
+      });
+    },
+    // 添加分类商品
+    addClassGoods(info) {
+      const { successText } = model("wordsModel");
+      const { success } = model("loadingModel");
+      const { httpPost } = model("httpModel");
+      return httpPost(
+        "/goodsSpecification/save",
+        info,
+        {
+          body: "json",
         },
         },
-        // 移除商品分类
-        removeCLass(info, callBack) {
-            const { showDialog } = model("dialogModel");
-            const { removeTips, editSuccess } = model("wordsModel");
-            const { httpPost } = model("httpModel");
-            const { success } = model("loadingModel");
+        true
+      ).then(res => {
+        success(successText);
+        return Promise.resolve(res);
+      });
+    },
+    // 移除商品分类
+    removeCLass(info, callBack) {
+      const { showDialog } = model("dialogModel");
+      const { removeTips, editSuccess } = model("wordsModel");
+      const { httpPost } = model("httpModel");
+      const { success } = model("loadingModel");
+      showDialog({
+        bodyText: removeTips,
+        status: "danger",
+        cancelable: true,
+        confirmCallback: () => {
+          const goods = new ListUtil(info.goodsIds);
+          if (goods.length > 0) {
             showDialog({
             showDialog({
-                bodyText: removeTips,
-                status: "danger",
-                cancelable: true,
-                confirmCallback: () => {
-                    const goods = new ListUtil(info.goodsIds);
-                    if (goods.length > 0) {
-                        showDialog({
-                            bodyText: "该分类下有商品,暂不可删除该商品分类",
-                            status: "danger",
-                        });
-                    } else {
-                        httpPost(
-                            `/classification/del/${  info.id}`,
-                            {},
-                            {},
-                            true
-                        ).then(res => {
-                            success(editSuccess);
-                            callBack(res);
-                        });
-                    }
-                },
+              bodyText: "该分类下有商品,暂不可删除该商品分类",
+              status: "danger",
             });
             });
-        },
-
-        // 商品分类添加商品
-        addClassification(selectId, goodsId) {
-            const { httpGet } = model("httpModel");
-            return httpGet(
-                "/classification/saveGoods",
-                {
-                    classificationId: selectId,
-                    string: goodsId,
-                },
-                { body: "json" }
+          } else {
+            httpPost(`/classification/del/${info.id}`, {}, {}, true).then(
+              res => {
+                success(editSuccess);
+                callBack(res);
+              }
             );
             );
+          }
         },
         },
-        // 将当前选中的classId存入以便更好的刷新页面3
-        setClassificationId(id) {
-            setState({
-                classificationId: id,
-            });
-        },
-        // 获取我的全部商品分类
-        getMyClassification() {
-            const { httpGet } = model("httpModel");
-            return httpGet("/classification/my", {}, true).then(res => {
-                res = res.sort((a, b) => {
-                    return b.type || 0 - a.type || 0;
-                });
+      });
+    },
 
 
-                setState({ Classifications: res });
-                return Promise.resolve(res);
-            });
+    // 商品分类添加商品
+    addClassification(selectId, goodsId) {
+      const { httpGet } = model("httpModel");
+      return httpGet(
+        "/classification/saveGoods",
+        {
+          classificationId: selectId,
+          string: goodsId,
         },
         },
-    }),
+        { body: "json" }
+      );
+    },
+    // 将当前选中的classId存入以便更好的刷新页面3
+    setClassificationId(id) {
+      setState({
+        classificationId: id,
+      });
+    },
+    // 获取我的全部商品分类
+    getMyClassification() {
+      const { httpGet } = model("httpModel");
+      return httpGet("/classification/my", {}, true).then(res => {
+        res = res.sort((a, b) => {
+          return b.type || 0 - a.type || 0;
+        });
+
+        setState({ Classifications: res });
+        return Promise.resolve(res);
+      });
+    },
+
+    // 商品规格排序
+    sortClassification(list) {
+      const _list = [...list];
+      let backList = [];
+      const parents = _list.filter(item => {
+        return !item.parent;
+      });
+      parents.forEach(item => {
+        backList.push(item);
+        const _chidrens = _list.filter(_f => {
+          return _f.parent === item.id;
+        });
+        backList = backList.concat(_chidrens);
+      });
+
+      return backList;
+    },
+  }),
 };
 };

+ 242 - 251
screens/FullReduction.js

@@ -1,16 +1,14 @@
 /* eslint-disable no-underscore-dangle */
 /* eslint-disable no-underscore-dangle */
 import * as WebBrowser from "expo-web-browser";
 import * as WebBrowser from "expo-web-browser";
 import * as React from "react";
 import * as React from "react";
+import { StyleSheet } from "react-native";
 import {
 import {
-    StyleSheet,
-} from "react-native";
-import {
-    Layout,
-    Text,
-    useTheme,
-    Button,
-    List,
-    Input,
+  Layout,
+  Text,
+  useTheme,
+  Button,
+  List,
+  Input,
 } from "@ui-kitten/components";
 } from "@ui-kitten/components";
 import { useModel } from "flooks";
 import { useModel } from "flooks";
 import { useFocusEffect } from "@react-navigation/native";
 import { useFocusEffect } from "@react-navigation/native";
@@ -18,271 +16,264 @@ import ActionButton from "react-native-action-button";
 import EmptyComponent from "../components/EmptyComponent";
 import EmptyComponent from "../components/EmptyComponent";
 import NavHeaderBar from "../components/NavHeaderBar";
 import NavHeaderBar from "../components/NavHeaderBar";
 
 
-
 const styles = StyleSheet.create({
 const styles = StyleSheet.create({
-    all: {
-        backgroundColor: "#fff",
-        flex: 1,
-    },
-    lay: {
-        backgroundColor: "#fff",
-    },
-    padBot: {
-        paddingBottom: 100,
-    },
-    list: {
-        paddingVertical: 10,
-        paddingHorizontal: 15,
-        backgroundColor: "transparent",
-        flex: 1,
-    },
-    item: {
-        flexDirection: "row",
-        alignItems: "center",
-        paddingVertical: 10,
-    },
-    input: {
-        marginHorizontal: 5,
-        minWidth: 49,
-    },
-    text: {
-        flex: 1,
-    },
-    flexRow: {
-        flexDirection: "row",
-        alignItems: "center",
-    },
-    buttonlast: {
-        marginLeft: 10,
-    },
-    button: {
-        alignSelf: "flex-start",
-    },
+  all: {
+    backgroundColor: "#fff",
+    flex: 1,
+  },
+  lay: {
+    backgroundColor: "#fff",
+  },
+  padBot: {
+    paddingBottom: 100,
+  },
+  list: {
+    paddingVertical: 10,
+    paddingHorizontal: 15,
+    backgroundColor: "transparent",
+    flex: 1,
+  },
+  item: {
+    flexDirection: "row",
+    alignItems: "center",
+    paddingVertical: 10,
+  },
+  input: {
+    marginHorizontal: 5,
+    minWidth: 49,
+  },
+  text: {
+    flex: 1,
+  },
+  flexRow: {
+    flexDirection: "row",
+    alignItems: "center",
+  },
+  buttonlast: {
+    marginLeft: 10,
+  },
+  button: {
+    alignSelf: "flex-start",
+  },
 });
 });
 
 
-
-
 export default function FullReduction() {
 export default function FullReduction() {
-    const theme = useTheme();
-    const { changeBackground } = useModel("barModel", true);
-    const { mid } = useModel("userModel");
-    const { httpGet, httpPost } = useModel("httpModel", true);
-    const { success, warnning } = useModel("loadingModel", true);
-    const { showDialog } = useModel("dialogModel");
-
-    const {
-        userTitle21,
-        fullReduction2,
-        fullReduction1,
-        delText,
-        editText,
-        confirm,
-        cancel,
-        successText,
-        removeTips,
-    } = useModel("wordsModel");
-    const [fullReductions, changeFllReduction] = React.useState([
-        { fullAmount: "", minusAmount: "" },
-    ]);
-    useFocusEffect(
-        React.useCallback(() => {
-            changeBackground(theme["color-primary-500"]);
+  const theme = useTheme();
+  const { changeBackground } = useModel("barModel", true);
+  const { mid } = useModel("userModel");
+  const { httpGet, httpPost } = useModel("httpModel", true);
+  const { success, warnning } = useModel("loadingModel", true);
+  const { showDialog } = useModel("dialogModel");
 
 
-            httpGet("/fullReduction/my").then(res => {
-                if (res.length > 0) {
-                    changeFllReduction(
-                        res.map(item => {
-                            return { ...item, edit: false };
-                        })
-                    );
-                }
-            });
-        }, [])
-    );
+  const {
+    userTitle21,
+    fullReduction2,
+    fullReduction1,
+    delText,
+    editText,
+    confirm,
+    cancel,
+    successText,
+    removeTips,
+  } = useModel("wordsModel");
+  const [fullReductions, changeFllReduction] = React.useState([
+    { fullAmount: "", minusAmount: "" },
+  ]);
+  useFocusEffect(
+    React.useCallback(() => {
+      changeBackground(theme["color-primary-500"]);
 
 
-	const editInfo = (info, index) => {
-        const _fullReductions = [...fullReductions];
-        info.edit = true;
-        _fullReductions[index] = info;
-        changeFllReduction(_fullReductions);
-    };
-    const delInfo = (info, index) => {
-        showDialog({
-            bodyText: removeTips,
-            status: "danger",
-            cancelable: true,
-            confirmCallback: () => {
-                httpPost(`/fullReduction/del/${  info.id}`)
-                    .then(() => {
-                        success(successText);
-                        const _fullReductions = [...fullReductions];
-                        _fullReductions.splice(index, 1);
-                        changeFllReduction(_fullReductions);
-                    })
-                    .catch(e => {
-                        warnning(e.error);
-                    });
-            },
-        });
-    };
-    const cancelInfo = (info, index) => {
-        const _fullReductions = [...fullReductions];
-        if (info.id) {
-            info.edit = false;
-            _fullReductions[index] = info;
-        } else {
-            _fullReductions.pop();
+      httpGet("/fullReduction/my").then(res => {
+        if (res.length > 0) {
+          changeFllReduction(
+            res.map(item => {
+              return { ...item, edit: false };
+            })
+          );
         }
         }
+      });
+    }, [])
+  );
 
 
-        changeFllReduction(_fullReductions);
-    };
-    const saveInfo = (info, index) => {
-        httpPost(
-            "/fullReduction/save",
-            {
-                ...info,
-                merchantId: mid,
-            },
-            {
-                body: "json",
-            }
-        )
-            .then(res => {
-                success(successText);
-                const _fullReductions = [...fullReductions];
-                _fullReductions.splice(index, 1, {
-                    ...res,
-                    edit: false,
-                });
-                changeFllReduction(_fullReductions);
-            })
-            .catch(e => {
-                warnning(e.error);
-            });
-    };
-    function changeText(value, index, type) {
+  const editInfo = (info, index) => {
+    const _fullReductions = [...fullReductions];
+    info.edit = true;
+    _fullReductions[index] = info;
+    changeFllReduction(_fullReductions);
+  };
+  const delInfo = (info, index) => {
+    showDialog({
+      bodyText: removeTips,
+      status: "danger",
+      cancelable: true,
+      confirmCallback: () => {
+        httpPost(`/fullReduction/del/${info.id}`)
+          .then(() => {
+            success(successText);
+            const _fullReductions = [...fullReductions];
+            _fullReductions.splice(index, 1);
+            changeFllReduction(_fullReductions);
+          })
+          .catch(e => {
+            warnning(e.error);
+          });
+      },
+    });
+  };
+  const cancelInfo = (info, index) => {
+    const _fullReductions = [...fullReductions];
+    if (info.id) {
+      info.edit = false;
+      _fullReductions[index] = info;
+    } else {
+      _fullReductions.pop();
+    }
+
+    changeFllReduction(_fullReductions);
+  };
+  const saveInfo = (info, index) => {
+    httpPost(
+      "/fullReduction/save",
+      {
+        ...info,
+        merchantId: mid,
+      },
+      {
+        body: "json",
+      }
+    )
+      .then(res => {
+        success(successText);
         const _fullReductions = [...fullReductions];
         const _fullReductions = [...fullReductions];
-        const info = _fullReductions[index];
-        if (type === "full") {
-            info.fullAmount = value;
-        } else {
-            info.minusAmount = value;
-        }
-        _fullReductions.splice(index, 1, info);
+        _fullReductions.splice(index, 1, {
+          ...res,
+          edit: false,
+        });
         changeFllReduction(_fullReductions);
         changeFllReduction(_fullReductions);
+      })
+      .catch(e => {
+        warnning(e.error);
+      });
+  };
+  function changeText(value, index, type) {
+    const _fullReductions = [...fullReductions];
+    const info = _fullReductions[index];
+    if (type === "full") {
+      info.fullAmount = value;
+    } else {
+      info.minusAmount = value;
     }
     }
-    const addFullReduction = () => {
-        const _fullReductions = [...fullReductions];
-        const last = _fullReductions[_fullReductions.length - 1];
-        if (last.id) {
-            _fullReductions.push({
-                fullAmount: "",
-                minusAmount: "",
-            });
-            changeFllReduction(_fullReductions);
-        }
-	};
-	
+    _fullReductions.splice(index, 1, info);
+    changeFllReduction(_fullReductions);
+  }
+  const addFullReduction = () => {
+    const _fullReductions = [...fullReductions];
+    const last = _fullReductions[_fullReductions.length - 1];
+    if (last.id) {
+      _fullReductions.push({
+        fullAmount: "",
+        minusAmount: "",
+      });
+      changeFllReduction(_fullReductions);
+    }
+  };
 
 
-    const saveItem = (info, index) => (
-      <Layout style={styles.item}>
-        <Text style={styles.text}>
-          {fullReduction1}
-          {info.fullAmount}
-          {fullReduction2}
-          {info.minusAmount}
-        </Text>
+  const saveItem = (info, index) => (
+    <Layout style={styles.item}>
+      <Text style={styles.text}>
+        {fullReduction1}
+        {info.fullAmount}
+        {fullReduction2}
+        {info.minusAmount}
+      </Text>
 
 
-        <Button
-          size='small'
-          appearance='outline'
-          onPress={() => editInfo(info, index)}
-        >
-          {editText}
-        </Button>
-        <Button
-          size='small'
-          status='danger'
-          style={styles.buttonlast}
-          onPress={() => delInfo(info, index)}
-        >
-          {delText}
-        </Button>
-      </Layout>
-    );
+      <Button
+        size="small"
+        appearance="outline"
+        onPress={() => editInfo(info, index)}
+      >
+        {editText}
+      </Button>
+      <Button
+        size="small"
+        status="danger"
+        style={styles.buttonlast}
+        onPress={() => delInfo(info, index)}
+      >
+        {delText}
+      </Button>
+    </Layout>
+  );
 
 
-    const editItem = (info, index) => (
-      <Layout style={styles.item}>
-        <Layout style={[styles.text, styles.flexRow]}>
-          <Text>{fullReduction1}</Text>
-          <Input
-            size='small'
-            defaultValue={info.fullAmount.toString()}
-            style={styles.input}
-            key={index + 0}
-            keyboardType='numeric'
-            onChangeText={value => changeText(value, index, "full")}
-          />
-          <Text>{fullReduction2}</Text>
-          <Input
-            size='small'
-            defaultValue={info.minusAmount.toString()}
-            style={styles.input}
-            key={index + 1}
-            keyboardType='numeric'
-            onChangeText={value => changeText(value, index, "minus")}
-          />
-        </Layout>
+  const editItem = (info, index) => (
+    <Layout style={styles.item}>
+      <Layout style={[styles.text, styles.flexRow]}>
+        <Text>{fullReduction1}</Text>
+        <Input
+          size="small"
+          defaultValue={info.fullAmount.toString()}
+          style={styles.input}
+          key={`${index  }_0`}
+          keyboardType="numeric"
+          onChangeText={value => changeText(value, index, "full")}
+        />
+        <Text>{fullReduction2}</Text>
+        <Input
+          size="small"
+          defaultValue={info.minusAmount.toString()}
+          style={styles.input}
+          key={`${index  }_1`}
+          keyboardType="numeric"
+          onChangeText={value => changeText(value, index, "minus")}
+        />
+      </Layout>
 
 
+      <Button
+        size="small"
+        disabled={!info.minusAmount || !info.fullAmount}
+        onPress={() => saveInfo(info, index)}
+      >
+        {confirm}
+      </Button>
+      {!!info.id && (
         <Button
         <Button
-          size='small'
-          disabled={!info.minusAmount || !info.fullAmount}
-          onPress={() => saveInfo(info, index)}
-        >
-          {confirm}
-        </Button>
-        {!!info.id && (
-        <Button
-          size='small'
-          appearance='outline'
+          size="small"
+          appearance="outline"
           style={styles.buttonlast}
           style={styles.buttonlast}
           onPress={() => cancelInfo(info, index)}
           onPress={() => cancelInfo(info, index)}
         >
         >
           {cancel}
           {cancel}
         </Button>
         </Button>
-            )}
-      </Layout>
-    );
+      )}
+    </Layout>
+  );
 
 
-	const renderItem = ({ item, index }) => {
-        if (!item.id || item.edit) {
-            return editItem(item, index);
-        } 
-            return saveItem(item);
-        
-    };
+  const renderItem = ({ item, index }) => {
+    if (!item.id || item.edit) {
+      return editItem(item, index);
+    }
+    return saveItem(item);
+  };
 
 
-    return (
-      <>
-        <NavHeaderBar title={userTitle21} />
-        <Layout style={styles.all}>
-          <Layout style={[styles.all]}>
-            <List
-              style={styles.list}
-              data={fullReductions}
-              renderItem={renderItem}
-              ListEmptyComponent={EmptyComponent}
-              keyboardShouldPersistTaps='handled'
-            />
-          </Layout>
-          <ActionButton
-            buttonColor={theme["color-primary-500"]}
-            onPress={addFullReduction}
-            position='left'
+  return (
+    <>
+      <NavHeaderBar title={userTitle21} />
+      <Layout style={styles.all}>
+        <Layout style={[styles.all]}>
+          <List
+            style={styles.list}
+            data={fullReductions}
+            renderItem={renderItem}
+            ListEmptyComponent={EmptyComponent}
+            keyboardShouldPersistTaps="handled"
           />
           />
         </Layout>
         </Layout>
-      </>
-    );
+        <ActionButton
+          buttonColor={theme["color-primary-500"]}
+          onPress={addFullReduction}
+          position="left"
+        />
+      </Layout>
+    </>
+  );
 }
 }
-
-

+ 390 - 290
screens/Goods/GoodsSpecificationScreen.js

@@ -1,330 +1,430 @@
+/* eslint-disable no-else-return */
+/* eslint-disable prefer-const */
+/* eslint-disable react/jsx-one-expression-per-line */
 /* eslint-disable no-underscore-dangle */
 /* eslint-disable no-underscore-dangle */
 /* eslint-disable no-shadow */
 /* eslint-disable no-shadow */
 import * as WebBrowser from "expo-web-browser";
 import * as WebBrowser from "expo-web-browser";
 import * as React from "react";
 import * as React from "react";
-import {
-    StyleSheet,
-} from "react-native";
+import { StyleSheet, View } from "react-native";
 import { useModel } from "flooks";
 import { useModel } from "flooks";
 import {
 import {
-    Layout,
-    Text,
-    useTheme,
-    Button,
-    Input,
+  Layout,
+  Text,
+  useTheme,
+  Button,
+  Input,
+  Toggle,
 } from "@ui-kitten/components";
 } from "@ui-kitten/components";
 import { useFocusEffect, useRoute } from "@react-navigation/native";
 import { useFocusEffect, useRoute } from "@react-navigation/native";
 import ActionButton from "react-native-action-button";
 import ActionButton from "react-native-action-button";
 import ListComponent from "../../components/ListComponent";
 import ListComponent from "../../components/ListComponent";
 import NavHeaderBar from "../../components/NavHeaderBar";
 import NavHeaderBar from "../../components/NavHeaderBar";
 
 
-
-
 const styles = StyleSheet.create({
 const styles = StyleSheet.create({
-    lay: {
-        backgroundColor: "#fff",
-        flex: 1,
-    },
-    padBot: {
-        paddingBottom: 100,
-    },
-    list: {
-        paddingVertical: 10,
-        paddingHorizontal: 15,
-        backgroundColor: "transparent",
-        flex: 0,
-    },
-    item: {
-        flexDirection: "row",
-        alignItems: "center",
-        paddingVertical: 10,
-    },
-    input: {
-        marginHorizontal: 5,
-        minWidth: 49,
-    },
-    text: {
-        flex: 1,
-    },
-    flexRow: {
-        flexDirection: "row",
-        alignItems: "center",
-    },
-    buttonlast: {
-        marginLeft: 10,
-    },
-    button: {
-        alignSelf: "flex-start",
-    },
-    money: {
-        marginLeft: 10,
-    },
+  lay: {
+    backgroundColor: "#fff",
+    flex: 1,
+  },
+  padBot: {
+    paddingBottom: 100,
+  },
+  list: {
+    paddingVertical: 10,
+    paddingHorizontal: 15,
+    backgroundColor: "transparent",
+    flex: 0,
+  },
+  item: {
+    flexDirection: "row",
+    alignItems: "center",
+    paddingVertical: 10,
+  },
+  input: {
+    marginHorizontal: 5,
+    minWidth: 49,
+    // width: 49,
+  },
+  text: {
+    flex: 1,
+  },
+  flexRow: {
+    flexDirection: "row",
+    alignItems: "center",
+  },
+  buttonlast: {
+    marginLeft: 10,
+  },
+  button: {
+    alignSelf: "flex-start",
+  },
+  money: {
+    marginLeft: 10,
+  },
+  addNew2: {
+    width: 80,
+    alignSelf: "center",
+  },
 });
 });
 
 
-
 export default function GoodsSpecificationScreen() {
 export default function GoodsSpecificationScreen() {
-    const theme = useTheme();
-    const { changeBackground } = useModel("barModel", true);
-    // const { mid } = useModel("userModel");
-    const { httpGet, httpPost } = useModel("httpModel", true);
-    const { success, warnning } = useModel("loadingModel", true);
-    const { showDialog } = useModel("dialogModel");
-    const [allEditInfo, setEdit] = React.useState({});
-    const [goodsId, setGoodsId] = React.useState(0);
-    const [startState, changeState] = React.useState(true);
-    const [editList, setEditList] = React.useState([]);
-    const [addNew, changeNew] = React.useState(false);
-    const [isNew, changeIsNew] = React.useState(false);
+  const theme = useTheme();
+  const { changeBackground } = useModel("barModel", true);
+  // const { mid } = useModel("userModel");
+  const { httpGet, httpPost } = useModel("httpModel", true);
+  const { success, warnning } = useModel("loadingModel", true);
+  const { showDialog } = useModel("dialogModel");
+  const [allEditInfo, setEdit] = React.useState([]);
+  const [goodsId, setGoodsId] = React.useState(0);
+  const [startState, changeState] = React.useState(true);
+  const [editList, setEditList] = React.useState([]);
+  const [addNew, changeNew] = React.useState([]);
 
 
-    const {
-        delText,
-        editText,
-        confirm,
-        cancel,
-        successText,
-        removeTips,
-    } = useModel("wordsModel");
-    const { addClassGoods } = useModel("goodsModel");
-    useFocusEffect(
-        React.useCallback(() => {
-            changeBackground(theme["color-primary-500"]);
-        }, [])
-    );
+  const {
+    delText,
+    editText,
+    confirm,
+    cancel,
+    successText,
+    removeTips,
+  } = useModel("wordsModel");
+  const { addClassGoods } = useModel("goodsModel");
+  useFocusEffect(
+    React.useCallback(() => {
+      changeBackground(theme["color-primary-500"]);
+    }, [])
+  );
 
 
-    const route = useRoute();
+  const route = useRoute();
 
 
-    function getList() {
-        const { params } = route;
-        const { goodsId } = params || {};
-        setGoodsId(goodsId);
-        return httpGet(
-            "/goodsSpecification/byGoodsId",
-            {
-                goodsId: goodsId || 0,
-            },
-            true
-        ).then(res => {
-            changeState(false);
-            if (res.length === 0) {
-                changeIsNew(true);
-            } else {
-                changeIsNew(false);
-            }
-            const content = res || [];
-            if (isNew || addNew) {
-                content.push({ name: "", amount: "" });
-            }
-
-            return Promise.resolve({
-                content: content.map(item => {
-                    const _info = { ...item, amount: item.amount.toString() };
-
-                    if (!_info.id || editList.indexOf(_info.id) !== -1) {
-                        _info.edit = true;
-                    } else {
-                        _info.edit = false;
-                    }
-                    return _info;
-                }),
-                last: true,
-            });
+  function getList() {
+    const { params } = route;
+    const { goodsId } = params || {};
+    setGoodsId(goodsId);
+    return httpGet(
+      "/goodsSpecification/byGoodsId",
+      {
+        goodsId: goodsId || 0,
+      },
+      true
+    ).then(res => {
+      changeState(false);
+      let isNew = false;
+      if (res.length === 0) {
+        isNew = true;
+        changeNew([]);
+      } else {
+        isNew = false;
+      }
+      let content = [];
+      if (res.length > 0) {
+        let parents = res.filter(item => {
+          return !item.parent;
         });
         });
-	}
-
-	const editInfo = id => {
-        const _editList = [...editList];
-        _editList.push(id);
-        setEditList(_editList);
-        changeState(true);
-    };
-    const delInfo = (info) => {
-        showDialog({
-            bodyText: removeTips,
-            status: "danger",
-            cancelable: true,
-            confirmCallback: () => {
-                httpPost(`/goodsSpecification/del/${  info.id}`)
-                    .then(() => {
-                        success(successText);
-                        changeState(true);
-                    })
-                    .catch(e => {
-                        warnning(e.error);
-                    });
-            },
+        parents.forEach(item => {
+          content.push(item);
+          let _children = res.filter(_f => {
+            return _f.parent === item.id;
+          });
+          content = content.concat(_children);
         });
         });
-    };
-    // 取消
-    const cancelInfo = info => {
-        const _editInfo = { ...allEditInfo };
-        _editInfo[info.id || "new"] = {};
-        setEdit(_editInfo);
+      }
 
 
-        if (info.id) {
-            let _editList = [...editList];
-            _editList = _editList.filter(item => {
-                return item !== info.id;
+      if (isNew) {
+        content.push({ name: "", multiple: false });
+      } else {
+        addNew.forEach((item, index) => {
+          if (item.addType === "1") {
+            content.push({ name: "", multiple: false, addIndex: index });
+          } else {
+            let _index = content.findIndex(_i => {
+              return _i.id === item.parent;
             });
             });
-            setEditList(_editList);
-        } else if (!isNew) {
-            changeNew(false);
-        }
-        changeState(true);
-    };
-    // 保存
-    const saveInfo = info => {
-        const _editInfo = { ...allEditInfo };
-        let name = "";
-        let amount = "";
-        if (_editInfo[info.id || "new"]) {
-            name = _editInfo[info.id || "new"].name;
-            amount = _editInfo[info.id || "new"].amount;
-        }
-        const data = {
-            ...info,
-            name,
-            amount,
-            goodsId,
+            content.splice(_index + 1, 0, {
+              name: "",
+              amount: "",
+              parent: item.parent,
+              addIndex: index,
+            });
+          }
+        });
+      }
+      content = content.map(item => {
+        const _info = {
+          ...item,
+          amount: item.amount ? item.amount.toString() : "",
         };
         };
-        if (!info.id && !isNew) {
-            changeNew(false);
+        if (!_info.id || editList.indexOf(_info.id) !== -1) {
+          _info.edit = true;
+        } else {
+          _info.edit = false;
         }
         }
+        return _info;
+      });
+      setEdit(content);
 
 
-        addClassGoods(data).then(res => {
-            _editInfo.new = {};
-            _editInfo[res.id] = {};
-            setEdit(_editInfo);
-            let _editList = [...editList];
-            _editList = _editList.filter(item => {
-                return item !== res.id;
+      return Promise.resolve({
+        content,
+        last: true,
+      });
+    });
+  }
+
+  const editInfo = id => {
+    const _editList = [...editList];
+    _editList.push(id);
+    setEditList(_editList);
+    changeState(true);
+  };
+  const delInfo = info => {
+    showDialog({
+      bodyText: removeTips,
+      status: "danger",
+      cancelable: true,
+      confirmCallback: () => {
+        if (!info.parent) {
+          let _allEditInfo = [...allEditInfo];
+          let _children = _allEditInfo.filter(item => {
+            return item.parent === info.id;
+          });
+          if (_children.length > 0) {
+            showDialog({
+              bodyText: "当前分类存在规格,请删除规格后再删除",
+              status: "danger",
             });
             });
-            setEditList(_editList);
+            return;
+          }
+        }
+        httpPost(`/goodsSpecification/del/${info.id}`)
+          .then(() => {
+            success(successText);
             changeState(true);
             changeState(true);
-        });
-    };
-
-	
-	const saveItem = (info, index) => (
-  <Layout style={styles.item}>
-    <Layout style={[styles.text, styles.flexRow]}>
-      <Text category='c1'>
-        添加
-        {info.name}
-      </Text>
-      <Layout style={styles.money}>
-        <Text category='c1'>
-          ¥
-          {info.amount}
-        </Text>
-      </Layout>
-    </Layout>
-  
-    <Button
-      size='small'
-      appearance='outline'
-      onPress={() => editInfo(info.id)}
-    >
-      {editText}
-    </Button>
-    <Button
-      size='small'
-      status='danger'
-      style={styles.buttonlast}
-      onPress={() => delInfo(info, index)}
-    >
-      {delText}
-    </Button>
-  </Layout>
-	  );
-  
-	  const editItem = (info, index) => (
-  <Layout style={styles.item}>
-    <Layout style={[styles.text, styles.flexRow]}>
-      <Text>规格</Text>
-      <Input
-        size='small'
-        defaultValue={info.name}
-        style={styles.input}
-        key={`${index  }_0`}
-        keyboardType='numeric'
-        onChangeText={text => {
-						  const _editInfo = { ...allEditInfo } || {};
-						  if (!_editInfo[info.id || "new"]) {
-							  _editInfo[info.id || "new"] = {};
-						  }
-						  _editInfo[info.id || "new"].name = text;
-						  setEdit(_editInfo);
-					  }}
-      />
-      <Text>价钱</Text>
-      <Input
-        size='small'
-        defaultValue={info.amount}
-        style={styles.input}
-        key={`${index  }_1`}
-        keyboardType='numeric'
-        onChangeText={text => {
-						  const _editInfo = { ...allEditInfo } || {};
-						  if (!_editInfo[info.id || "new"]) {
-							  _editInfo[info.id || "new"] = {};
-						  }
-						  _editInfo[info.id || "new"].amount = text;
-						  setEdit(_editInfo);
-					  }}
-      />
-    </Layout>
-  
-    <Button size='small' onPress={() => saveInfo(info)}>
-      {confirm}
-    </Button>
-    <Button
-      size='small'
-      appearance='outline'
-      style={styles.buttonlast}
-      onPress={() => cancelInfo(info)}
-    >
-      {cancel}
-    </Button>
-  </Layout>
-	  );
+          })
+          .catch(e => {
+            warnning(e.error);
+          });
+      },
+    });
+  };
+  // 取消
+  const cancelInfo = info => {
+    if (info.id) {
+      let _editList = [...editList];
+      _editList = _editList.filter(item => {
+        return item !== info.id;
+      });
+      setEditList(_editList);
+    } else {
+      let _addNew = [...addNew];
+      _addNew.splice(info.addIndex, 1);
+      changeNew(_addNew);
+    }
+    changeState(true);
+  };
 
 
-    const renderItem = ({ item, index }) => {
-        if (!item.id || item.edit) {
-            return editItem(item, index);
-        } 
-            return saveItem(item);
-        
+  // 保存
+  const saveInfo = info => {
+    // const _editInfo = { ...allEditInfo };
+    // let name = "";
+    // let amount = "";
+    // if (_editInfo[info.id || "new"]) {
+    //   name = _editInfo[info.id || "new"].name;
+    //   amount = _editInfo[info.id || "new"].amount;
+    // }
+    const data = {
+      ...info,
+      goodsId,
     };
     };
+    delete data.addIndex;
+    addClassGoods(data).then(() => {
+      if (info.id) {
+        let _editList = [...editList];
+        _editList = _editList.filter(item => {
+          return item !== info.id;
+        });
+        setEditList(_editList);
+      } else {
+        let _addNew = [...addNew];
+        _addNew.splice(info.addIndex, 1);
+        changeNew(_addNew);
+      }
+      changeState(true);
+    });
+  };
 
 
-   
+  //
+  const addFullReduction = info => {
+    let list = [...addNew];
+    let hasType1 = list.find(item => {
+      return item.addType === "1";
+    });
 
 
-    
-    //
-    const addFullReduction = () => {
-        changeNew(true);
+    if (info && info.parent) {
+      let hasParent = list.find(item => {
+        return item.parent === info.parent;
+      });
+      if (!hasParent) {
+        list.push(info);
+        changeNew(list);
         changeState(true);
         changeState(true);
-    };
+      }
+    } else if (!info && !hasType1) {
+      list.push({
+        addType: "1",
+      });
+      console.log(list);
+      changeNew(list);
+      changeState(true);
+    }
+  };
 
 
+  const saveItem = (info, index) => {
+    let editNowInfo = { ...info };
     return (
     return (
-      <>
-        <NavHeaderBar title='商品规格编辑' />
+      <View Key={index}>
+        <Layout style={styles.item}>
+          <Layout style={[styles.text, styles.flexRow]}>
+            {editNowInfo.parent ? (
+              <Text category="c1">添加{editNowInfo.name}</Text>
+            ) : (
+              <Text category="s1">分类名:{editNowInfo.name}</Text>
+            )}
+            {!!editNowInfo.parent && (
+              <Layout style={styles.money}>
+                <Text category="c1">¥{editNowInfo.amount}</Text>
+              </Layout>
+            )}
+            {!editNowInfo.parent && (
+              <Layout style={styles.money}>
+                <Text category="s1">
+                  {editNowInfo.multiple ? "多选" : "单选"}
+                </Text>
+              </Layout>
+            )}
+          </Layout>
 
 
-        <Layout style={[styles.lay]}>
-          <ListComponent
-            getInfo={getList}
-            renderItem={renderItem}
-            style={styles.list}
-            separatorStyle={styles.separatorStyle}
-            showEmpty
-            extraData={{ allEditInfo }}
-            startState={startState}
-          />
-          <ActionButton
-            buttonColor={theme["color-primary-500"]}
-            onPress={addFullReduction}
-            position='left'
+          <Button
+            size="small"
+            appearance="outline"
+            onPress={() => editInfo(editNowInfo.id)}
+          >
+            {editText}
+          </Button>
+          <Button
+            size="small"
+            status="danger"
+            style={styles.buttonlast}
+            onPress={() => delInfo(editNowInfo, index)}
+          >
+            {delText}
+          </Button>
+        </Layout>
+        {!editNowInfo.parent && (
+          <Button
+            style={styles.addNew2}
+            onPress={() =>
+              addFullReduction({ addType: "2", parent: editNowInfo.id })
+            }
+          >
+            添加规格
+          </Button>
+        )}
+      </View>
+    );
+  };
+
+  const editItem = (info, index) => {
+    let _allEditInfo = [...allEditInfo];
+    let editNowInfo = { ..._allEditInfo[index] };
+    return (
+      <Layout style={styles.item}>
+        <Layout style={[styles.text, styles.flexRow]}>
+          <Text>{editNowInfo.parent ? "规格" : "类名"}</Text>
+          <Input
+            size="small"
+            defaultValue={editNowInfo.name}
+            style={styles.input}
+            key={`${index}_0`}
+            onChangeText={text => {
+              editNowInfo.name = text;
+              _allEditInfo.splice(index, 1, editNowInfo);
+              setEdit(_allEditInfo);
+            }}
           />
           />
+          {!!editNowInfo.parent && (
+            <>
+              <Text>价钱</Text>
+              <Input
+                size="small"
+                defaultValue={info.amount}
+                style={styles.input}
+                key={`${index}_2`}
+                keyboardType="numeric"
+                onChangeText={text => {
+                  editNowInfo.amount = text;
+                  _allEditInfo.splice(index, 1, editNowInfo);
+                  setEdit(_allEditInfo);
+                }}
+              />
+            </>
+          )}
+          {!editNowInfo.parent && (
+            <>
+              <Text>是否多选</Text>
+              <Toggle
+                key="Toggle"
+                checked={editNowInfo.multiple}
+                onChange={checked => {
+                  editNowInfo.multiple = checked;
+                  _allEditInfo.splice(index, 1, editNowInfo);
+                  setEdit(_allEditInfo);
+                }}
+              />
+            </>
+          )}
         </Layout>
         </Layout>
-      </>
+
+        <Button size="small" onPress={() => saveInfo(editNowInfo)}>
+          {confirm}
+        </Button>
+        <Button
+          size="small"
+          appearance="outline"
+          style={styles.buttonlast}
+          onPress={() => cancelInfo(editNowInfo)}
+        >
+          {cancel}
+        </Button>
+      </Layout>
     );
     );
+  };
+
+  const renderItem = ({ item, index }) => {
+    if (!item.id || item.edit) {
+      return editItem(item, index);
+    }
+    return saveItem(item);
+  };
+
+  return (
+    <>
+      <NavHeaderBar title="商品规格编辑" />
+
+      <Layout style={[styles.lay]}>
+        <ListComponent
+          getInfo={getList}
+          renderItem={renderItem}
+          style={styles.list}
+          separatorStyle={styles.separatorStyle}
+          showEmpty
+          extraData={{ allEditInfo }}
+          startState={startState}
+        />
+        <ActionButton
+          buttonColor={theme["color-primary-500"]}
+          onPress={addFullReduction}
+          position="left"
+        />
+      </Layout>
+    </>
+  );
 }
 }

+ 365 - 386
screens/Guide1Screen.js

@@ -1,20 +1,13 @@
+/* eslint-disable react/jsx-one-expression-per-line */
 /* eslint-disable no-shadow */
 /* eslint-disable no-shadow */
 /* eslint-disable camelcase */
 /* eslint-disable camelcase */
 import * as WebBrowser from "expo-web-browser";
 import * as WebBrowser from "expo-web-browser";
 import * as React from "react";
 import * as React from "react";
-import {
-    StyleSheet,
-} from "react-native";
-import {
-    Layout,
-    Text,
-    useTheme,
-    Button,
-    Card,
-} from "@ui-kitten/components";
+import { StyleSheet } from "react-native";
+import { Layout, Text, useTheme, Button, Card } from "@ui-kitten/components";
 import { useModel } from "flooks";
 import { useModel } from "flooks";
 import { useFocusEffect, useRoute } from "@react-navigation/native";
 import { useFocusEffect, useRoute } from "@react-navigation/native";
-import moment from 'moment';
+import moment from "moment";
 import Textarea from "react-native-textarea";
 import Textarea from "react-native-textarea";
 import ScrollPage from "../components/ScrollPage";
 import ScrollPage from "../components/ScrollPage";
 import FormInput from "../components/FormInput";
 import FormInput from "../components/FormInput";
@@ -22,413 +15,399 @@ import ConnectButton from "../components/ConnectButton";
 import GuideHeaderBar from "../components/GuideHeaderBar";
 import GuideHeaderBar from "../components/GuideHeaderBar";
 import NavHeaderBar from "../components/NavHeaderBar";
 import NavHeaderBar from "../components/NavHeaderBar";
 
 
-
-
 const styles = StyleSheet.create({
 const styles = StyleSheet.create({
-    container: {
-        flex: 1,
-        paddingBottom: 33,
-    },
-    tabContent: {
-        backgroundColor: "#fff",
-        marginTop: 20,
-    },
-    img: {
-        width: 100,
-        height: 100,
-        alignSelf: "center",
-    },
-    img2: {
-        width: 97,
-        height: 21,
-        alignSelf: "center",
-        marginTop: 2,
-    },
-    text: {
-        marginTop: 16,
-    },
-    layoutLeft: {
-        // flexDirection: "row",
-        paddingVertical: 10,
-        justifyContent: "center",
-        alignItems: "center",
-    },
-    form: {
-        paddingHorizontal: 26,
-        paddingVertical: 20,
-    },
-    textareaContainer: {
-        backgroundColor: "#F0F0F0",
-        height: 100,
-        borderRadius: 4,
-    },
-    textarea: {
-        textAlignVertical: "top", // hack android
-        fontSize: 13,
-        color: "#333",
-        paddingHorizontal: 14,
-        paddingVertical: 10,
-        height: 100,
-    },
-    lay: {
-        flexDirection: "row",
-        marginLeft: 120,
-        marginBottom: 10,
-    },
-    money: {
-        marginLeft: 10,
-    },
+  container: {
+    flex: 1,
+    paddingBottom: 33,
+  },
+  tabContent: {
+    backgroundColor: "#fff",
+    marginTop: 20,
+  },
+  img: {
+    width: 100,
+    height: 100,
+    alignSelf: "center",
+  },
+  img2: {
+    width: 97,
+    height: 21,
+    alignSelf: "center",
+    marginTop: 2,
+  },
+  text: {
+    marginTop: 16,
+  },
+  layoutLeft: {
+    // flexDirection: "row",
+    paddingVertical: 10,
+    justifyContent: "center",
+    alignItems: "center",
+  },
+  form: {
+    paddingHorizontal: 26,
+    paddingVertical: 20,
+  },
+  textareaContainer: {
+    backgroundColor: "#F0F0F0",
+    height: 100,
+    borderRadius: 4,
+  },
+  textarea: {
+    textAlignVertical: "top", // hack android
+    fontSize: 13,
+    color: "#333",
+    paddingHorizontal: 14,
+    paddingVertical: 10,
+    height: 100,
+  },
+  lay: {
+    flexDirection: "row",
+    marginLeft: 120,
+    marginBottom: 10,
+  },
+  money: {
+    marginLeft: 10,
+  },
 });
 });
 
 
-
 export default function Guide1Screen({ navigation }) {
 export default function Guide1Screen({ navigation }) {
-    const theme = useTheme();
-    const { changeBackground } = useModel("barModel");
-    const { httpGet, httpPost } = useModel("httpModel", true);
-    const { success } = useModel("loadingModel", true);
-    const { mid, changeGuideStep } = useModel("userModel", true);
-    const { addClassification } = useModel("goodsModel", true);
+  const theme = useTheme();
+  const { changeBackground } = useModel("barModel");
+  const { httpGet, httpPost } = useModel("httpModel", true);
+  const { success } = useModel("loadingModel", true);
+  const { mid, changeGuideStep } = useModel("userModel", true);
+  const { addClassification, sortClassification } = useModel(
+    "goodsModel",
+    true
+  );
 
 
-    const {
-        guide1_title1,
-        guideHome_title2,
-        guide1_form_1,
-        guide1_pla_1,
-        guide1_form_2,
-        guide1_pla_2,
-        guide1_form_3,
-        guide1_pla_3,
-        guide1_form_4,
-        guide1_pla_4,
-        guide1_form_5,
-        guide1_pla_5,
-        next,
-        pass,
-        passTips,
-        confirm,
-        addGoods,
-        delText,
-        removeTips,
-    } = useModel("wordsModel");
-    const { showDialog } = useModel("dialogModel");
-    const route = useRoute();
-    const routeName = route.name;
-    const [id, changeId] = React.useState("");
+  const {
+    guide1_title1,
+    guideHome_title2,
+    guide1_form_1,
+    guide1_pla_1,
+    guide1_form_2,
+    guide1_pla_2,
+    guide1_form_3,
+    guide1_pla_3,
+    guide1_form_4,
+    guide1_pla_4,
+    guide1_form_5,
+    guide1_pla_5,
+    next,
+    pass,
+    passTips,
+    confirm,
+    addGoods,
+    delText,
+    removeTips,
+  } = useModel("wordsModel");
+  const { showDialog } = useModel("dialogModel");
+  const route = useRoute();
+  const routeName = route.name;
+  const [id, changeId] = React.useState("");
 
 
-    const [name, changeName] = React.useState("");
-    const [amount, changeAmount] = React.useState("");
-    const [discountAmount, changeDiscountAmount] = React.useState("");
-    const [inventory, changeInventory] = React.useState(0);
-    const [week, changeWeek] = React.useState("");
-    const [startTime, changeStartTime] = React.useState("08:00");
-    const [endTime, changeEndTime] = React.useState("22:00");
-    const [introduction, changeIntroduction] = React.useState();
-    const [defaultValue, ChangeDefaultValue] = React.useState("");
-    const [goodsSpecification, changeGoodsSpecification] = React.useState([]);
+  const [name, changeName] = React.useState("");
+  const [amount, changeAmount] = React.useState("");
+  const [discountAmount, changeDiscountAmount] = React.useState("");
+  const [inventory, changeInventory] = React.useState(0);
+  const [week, changeWeek] = React.useState("");
+  const [startTime, changeStartTime] = React.useState("08:00");
+  const [endTime, changeEndTime] = React.useState("22:00");
+  const [introduction, changeIntroduction] = React.useState();
+  const [defaultValue, ChangeDefaultValue] = React.useState("");
+  const [goodsSpecification, changeGoodsSpecification] = React.useState([]);
 
 
-    const [img, changeImg] = React.useState();
-  
-    function getInfo(res) {
-        changeName(res.name || "");
-        if (res.discountAmount) {
-            changeDiscountAmount(res.discountAmount.toString());
-        }
-        if (res.amount) {
-            changeAmount(res.amount.toString());
-        }
-        if (res.inventory) {
-            changeInventory(res.inventory.toString());
-        }
-        changeWeek(res.week || "");
-        changeStartTime(res.startTime || "");
-        changeEndTime(res.endTime || "");
-        changeIntroduction(res.introduction || "");
-        // if (res.img && res.img.length) {
-        changeImg(res.img);
-        // }
+  const [img, changeImg] = React.useState();
 
 
-        if (res.week) {
-            ChangeDefaultValue([
-                `${moment(res.startTime, "HH:mm:ss").format("HH:mm") 
-                    }~${ 
-                    moment(res.endTime, "HH:mm:ss").format("HH:mm")}`,
-                res.week,
-            ]);
-        }
+  function getInfo(res) {
+    changeName(res.name || "");
+    if (res.discountAmount) {
+      changeDiscountAmount(res.discountAmount.toString());
     }
     }
-    useFocusEffect(
-        React.useCallback(() => {
-            changeBackground(theme["color-primary-500"]);
-            const { params } = route;
-            if (params) {
-                if (params.id) {
-                    changeId(params.id);
-                    httpGet(`/goods/get/${params.id}`).then(res => {
-                        getInfo(res);
-                    });
-
-                    httpGet(
-                        "/goodsSpecification/byGoodsId",
-                        {
-                            goodsId: params.id,
-                        },
-                        true
-                    ).then(res => {
-                        changeGoodsSpecification(res);
-                    });
-                }
-            } else {
-                getInfo({});
-            }
-        }, [])
-    );
-
+    if (res.amount) {
+      changeAmount(res.amount.toString());
+    }
+    if (res.inventory) {
+      changeInventory(res.inventory.toString());
+    }
+    changeWeek(res.week || "");
+    changeStartTime(res.startTime || "");
+    changeEndTime(res.endTime || "");
+    changeIntroduction(res.introduction || "");
+    // if (res.img && res.img.length) {
+    changeImg(res.img);
+    // }
 
 
-    const specify = () => {
-        return goodsSpecification.map(item => {
-            return (
-              <Layout key={item.id} style={styles.lay}>
-                <Text category='c1'>
-                  添加
-                  {item.name}
-                </Text>
-                <Layout style={styles.money}>
-                  <Text category='c1'>
-                    ¥
-                    {item.amount}
-                  </Text>
-                </Layout>
-              </Layout>
-            );
-        });
-    };
+    if (res.week) {
+      ChangeDefaultValue([
+        `${moment(res.startTime, "HH:mm:ss").format("HH:mm")}~${moment(
+          res.endTime,
+          "HH:mm:ss"
+        ).format("HH:mm")}`,
+        res.week,
+      ]);
+    }
+  }
+  useFocusEffect(
+    React.useCallback(() => {
+      changeBackground(theme["color-primary-500"]);
+      const { params } = route;
+      if (params) {
+        if (params.id) {
+          changeId(params.id);
+          httpGet(`/goods/get/${params.id}`).then(res => {
+            getInfo(res);
+          });
 
 
-    const canNext = React.useMemo(() => {
-        if (
-            name &&
-            amount &&
-            inventory &&
-            week &&
-            startTime &&
-            endTime &&
-            img
-        ) {
-            return true;
-        } 
-            return false;
-        
-    }, [
-        name,
-        amount,
-        discountAmount,
-        inventory,
-        week,
-        startTime,
-        endTime,
-        introduction,
-        img,
-    ]);
+          httpGet(
+            "/goodsSpecification/byGoodsId",
+            {
+              goodsId: params.id,
+            },
+            true
+          ).then(res => {
+            changeGoodsSpecification(sortClassification(res));
+          });
+        }
+      } else {
+        getInfo({});
+      }
+    }, [])
+  );
 
 
-    return (
-      <>
-        {routeName !== "AddGoods" ? (
-          <GuideHeaderBar />
+  const specify = () => {
+    return goodsSpecification.map(item => {
+      return (
+        <Layout key={item.id} style={styles.lay}>
+          {item.parent ? (
+            <Text category="h1">
+              添加
+              {item.name}
+            </Text>
+          ) : (
+            <Text category="c1">
+              分类名:
+              {item.name}
+            </Text>
+          )}
+          <Layout style={styles.money}>
+            {item.parent ? (
+              <Text category="h1">¥{item.amount}</Text>
             ) : (
             ) : (
-              <NavHeaderBar title={addGoods} />
+              <Text category="c1">{item.multiple ? "多选" : "单选"}</Text>
             )}
             )}
+          </Layout>
+        </Layout>
+      );
+    });
+  };
 
 
-        <ScrollPage>
-          <Layout style={styles.container}>
-            {routeName !== "AddGoods" && (
-            <Card appearance='headFilled'>
-              <Text category='s1'>{guide1_title1}</Text>
-              <Text category='s1'>{guideHome_title2}</Text>
-            </Card>
-                    )}
-            <Card appearance='formFilled'>
-              {/* 商品名称 */}
-              <FormInput
-                label={guide1_form_1}
-                placeholder={guide1_pla_1}
-                value={name}
-                onChange={changeName}
-                style={{ paddingVertical: 3 }}
-              />
-              {/* 商品价格 */}
-              <FormInput
-                label={guide1_form_2}
-                placeholder={guide1_pla_2}
-                value={amount}
-                type='money'
-                onChange={changeAmount}
-                textAlign='right'
-              />
-
-              {/* 优惠价格 */}
-              <FormInput
-                label={guide1_form_3}
-                placeholder={guide1_pla_3}
-                value={discountAmount}
-                type='money'
-                onChange={changeDiscountAmount}
-                textAlign='right'
-              />
-              {id !== 0 && (
-                <>
-                  {/* 商品规格 */}
-                  <FormInput
-                    label='商品规格'
-                    type='url'
-                    changePath={() => {
-                                        navigation.navigate(
-                                            "GoodsSpecification",
-                                            {
-                                                goodsId: id,
-                                            }
-                                        );
-                                    }}
-                    textAlign='right'
-                  />
-                  {specify()}
-                </>
-                        )}
+  const canNext = React.useMemo(() => {
+    if (name && amount && inventory && week && startTime && endTime && img) {
+      return true;
+    }
+    return false;
+  }, [
+    name,
+    amount,
+    discountAmount,
+    inventory,
+    week,
+    startTime,
+    endTime,
+    introduction,
+    img,
+  ]);
 
 
-              {/* 每日供应数量 */}
-              <FormInput
-                label={guide1_form_4}
-                placeholder={guide1_pla_4}
-                value={inventory}
-                type='amount'
-                onChange={changeInventory}
-              />
+  return (
+    <>
+      {routeName !== "AddGoods" ? (
+        <GuideHeaderBar />
+      ) : (
+        <NavHeaderBar title={addGoods} />
+      )}
 
 
-              {/* 供应时间 */}
-              <FormInput
-                label={guide1_form_5}
-                type='openTime'
-                defaultValue={defaultValue}
-                onChange={(week, startTime, endTime) => {
-                                changeWeek(week);
-                                changeStartTime(startTime);
-                                changeEndTime(endTime);
-                            }}
-              />
+      <ScrollPage>
+        <Layout style={styles.container}>
+          {routeName !== "AddGoods" && (
+            <Card appearance="headFilled">
+              <Text category="s1">{guide1_title1}</Text>
+              <Text category="s1">{guideHome_title2}</Text>
+            </Card>
+          )}
+          <Card appearance="formFilled">
+            {/* 商品名称 */}
+            <FormInput
+              label={guide1_form_1}
+              placeholder={guide1_pla_1}
+              value={name}
+              onChange={changeName}
+              style={{ paddingVertical: 3 }}
+            />
+            {/* 商品价格 */}
+            <FormInput
+              label={guide1_form_2}
+              placeholder={guide1_pla_2}
+              value={amount}
+              type="money"
+              onChange={changeAmount}
+              textAlign="right"
+            />
 
 
-              <Layout>
-                <Textarea
-                  containerStyle={styles.textareaContainer}
-                  style={styles.textarea}
-                  onChangeText={changeIntroduction}
-                  defaultValue={introduction}
-                  maxLength={50}
-                  placeholder={guide1_pla_5}
-                  placeholderTextColor="#B4B4B4"
-                  underlineColorAndroid="transparent"
+            {/* 优惠价格 */}
+            <FormInput
+              label={guide1_form_3}
+              placeholder={guide1_pla_3}
+              value={discountAmount}
+              type="money"
+              onChange={changeDiscountAmount}
+              textAlign="right"
+            />
+            {id !== 0 && (
+              <>
+                {/* 商品规格 */}
+                <FormInput
+                  label="商品规格"
+                  type="url"
+                  changePath={() => {
+                    navigation.navigate("GoodsSpecification", {
+                      goodsId: id,
+                    });
+                  }}
+                  textAlign="right"
                 />
                 />
-              </Layout>
+                {specify()}
+              </>
+            )}
+
+            {/* 每日供应数量 */}
+            <FormInput
+              label={guide1_form_4}
+              placeholder={guide1_pla_4}
+              value={inventory}
+              type="amount"
+              onChange={changeInventory}
+            />
+
+            {/* 供应时间 */}
+            <FormInput
+              label={guide1_form_5}
+              type="openTime"
+              defaultValue={defaultValue}
+              onChange={(week, startTime, endTime) => {
+                changeWeek(week);
+                changeStartTime(startTime);
+                changeEndTime(endTime);
+              }}
+            />
 
 
-              <FormInput
-                type='img'
-                value={img}
-                textAlign='right'
-                onChange={changeImg}
+            <Layout>
+              <Textarea
+                containerStyle={styles.textareaContainer}
+                style={styles.textarea}
+                onChangeText={changeIntroduction}
+                defaultValue={introduction}
+                maxLength={50}
+                placeholder={guide1_pla_5}
+                placeholderTextColor="#B4B4B4"
+                underlineColorAndroid="transparent"
               />
               />
+            </Layout>
 
 
-              <Layout style={styles.layoutLeft} level='1'>
-                <Button
-                  status='primary'
-                  disabled={!canNext}
-                  onPress={() => {
-                                    httpPost(
-                                        "/goods/save",
-                                        {
-                                            id,
-                                            name,
-                                            amount,
-                                            discountAmount,
-                                            inventory,
-                                            week,
-                                            startTime,
-                                            endTime,
-                                            introduction,
-                                            img,
-                                            merchantId: mid,
-                                        },
-                                        { body: "json" },
-                                        true
-                                    ).then(res => {
-                                        if (!id) {
-                                            const { params } = route;
-                                            const { classifyId } = params || {};
-                                            if (classifyId) {
-                                                addClassification(
-                                                    classifyId,
-                                                    res.id
-                                                );
-                                            }
-                                        }
-                                        success(
-                                            `${id ? "修改" : "添加"  }成功`
-                                        );
-                                        if (routeName !== "AddGoods") {
-                                            changeGuideStep(2);
-                                        } else {
-                                            navigation.goBack();
-                                        }
-                                    });
-                                }}
-                >
-                  {routeName !== "AddGoods" ? next : confirm}
-                </Button>
-                {routeName === "AddGoods" && id !== 0 && (
+            <FormInput
+              type="img"
+              value={img}
+              textAlign="right"
+              onChange={changeImg}
+            />
+
+            <Layout style={styles.layoutLeft} level="1">
+              <Button
+                status="primary"
+                disabled={!canNext}
+                onPress={() => {
+                  httpPost(
+                    "/goods/save",
+                    {
+                      id,
+                      name,
+                      amount,
+                      discountAmount,
+                      inventory,
+                      week,
+                      startTime,
+                      endTime,
+                      introduction,
+                      img,
+                      merchantId: mid,
+                    },
+                    { body: "json" },
+                    true
+                  ).then(res => {
+                    if (!id) {
+                      const { params } = route;
+                      const { classifyId } = params || {};
+                      if (classifyId) {
+                        addClassification(classifyId, res.id);
+                      }
+                    }
+                    success(`${id ? "修改" : "添加"}成功`);
+                    if (routeName !== "AddGoods") {
+                      changeGuideStep(2);
+                    } else {
+                      navigation.goBack();
+                    }
+                  });
+                }}
+              >
+                {routeName !== "AddGoods" ? next : confirm}
+              </Button>
+              {routeName === "AddGoods" && id !== 0 && (
                 <Button
                 <Button
-                  appearance='ghost'
-                  status='info'
+                  appearance="ghost"
+                  status="info"
                   style={{ marginTop: 10 }}
                   style={{ marginTop: 10 }}
                   onPress={() => {
                   onPress={() => {
-                                        showDialog({
-                                            bodyText: removeTips,
-                                            cancelable: true,
-                                            confirmCallback: () => {
-                                                httpPost(
-                                                    `/goods/del/${  id}`,
-                                                    {},
-                                                    {},
-                                                    true
-                                                ).then(() => {
-                                                    success("删除成功");
-                                                    navigation.goBack();
-                                                });
-                                            },
-                                        });
-                                    }}
+                    showDialog({
+                      bodyText: removeTips,
+                      cancelable: true,
+                      confirmCallback: () => {
+                        httpPost(`/goods/del/${id}`, {}, {}, true).then(() => {
+                          success("删除成功");
+                          navigation.goBack();
+                        });
+                      },
+                    });
+                  }}
                 >
                 >
                   {delText}
                   {delText}
                 </Button>
                 </Button>
-                            )}
-                {routeName !== "AddGoods" && (
+              )}
+              {routeName !== "AddGoods" && (
                 <Button
                 <Button
                   style={{ marginTop: 10 }}
                   style={{ marginTop: 10 }}
-                  appearance='ghost'
-                  status='primary'
+                  appearance="ghost"
+                  status="primary"
                   onPress={() => {
                   onPress={() => {
-                                        showDialog({
-                                            bodyText: passTips,
-                                            cancelable: true,
-                                            confirmCallback: () => {
-                                                changeGuideStep(2);
-                                            },
-                                        });
-                                    }}
+                    showDialog({
+                      bodyText: passTips,
+                      cancelable: true,
+                      confirmCallback: () => {
+                        changeGuideStep(2);
+                      },
+                    });
+                  }}
                 >
                 >
                   {pass}
                   {pass}
                 </Button>
                 </Button>
-                            )}
-              </Layout>
-            </Card>
-            {routeName !== "AddGoods" && <ConnectButton />}
-          </Layout>
-        </ScrollPage>
-      </>
-    );
+              )}
+            </Layout>
+          </Card>
+          {routeName !== "AddGoods" && <ConnectButton />}
+        </Layout>
+      </ScrollPage>
+    </>
+  );
 }
 }

+ 2 - 2
screens/Set/OrderSetting.js

@@ -109,7 +109,7 @@ export default function OrderSettingScreen({ navigation }) {
           title='接单提醒'
           title='接单提醒'
           accessoryRight={() => (
           accessoryRight={() => (
             <Toggle
             <Toggle
-              key='Toggle'
+              key='Toggle2'
               checked={voice1}
               checked={voice1}
               onChange={changeVoice1}
               onChange={changeVoice1}
             />
             />
@@ -120,7 +120,7 @@ export default function OrderSettingScreen({ navigation }) {
           title='骑手取餐提醒'
           title='骑手取餐提醒'
           accessoryRight={() => (
           accessoryRight={() => (
             <Toggle
             <Toggle
-              key='Toggle'
+              key='Toggle4'
               checked={voice2}
               checked={voice2}
               onChange={changeVoice2}
               onChange={changeVoice2}
             />
             />