Parcourir la source

修正商家注册

Nivek il y a 2 ans
Parent
commit
a44c3541ce

+ 0 - 18
README.md

@@ -1,18 +0,0 @@
-# Vue 3 + TypeScript + Vite
-
-This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
-
-## Recommended IDE Setup
-
-- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
-
-## Type Support For `.vue` Imports in TS
-
-TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
-
-If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
-
-1. Disable the built-in TypeScript Extension
-   1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
-   2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
-2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.

+ 1 - 1
src/api/store.ts

@@ -12,7 +12,7 @@ export const createStore = payload => {
 
 // 获取全部商店
 export const getAllStore = () => {
-    return axios.get(`${STORE_MODULE}/`, )
+    return axios.get(`${STORE_MODULE}/all`, )
         .then(res => {
             return res
         })

+ 28 - 7
src/api/user.ts

@@ -1,18 +1,39 @@
 import {axios} from '../utils/request'
 import {USER_MODULE} from './_prefix'
 
+type LoginInfo = {
+    phone: string,
+    password: string
+}
+
+type RegisterInfo = {
+    role: string,
+    name: string,
+    phone: string,
+    password: string,
+    address: string,
+    storeId: number | null,
+}
+
+type UpdateInfo = {
+    name: string | null,
+    password: string | null,
+    address: string | null,
+}
+
+// 如果有“Vue: This may be converted to an async function”警告,可以不管
 // 用户登录
-export const userLogin = payload => {
-    return axios.post(`${USER_MODULE}/login`,null, {params: payload})
+export const userLogin = (loginInfo: LoginInfo) => {
+    return axios.post(`${USER_MODULE}/login`, null, {params: loginInfo})
         .then(res => {
             return res
         })
 }
 
 // 用户注册
-export const userRegister = payload => {
-    return axios.post(`${USER_MODULE}/register`, payload,
-                    {headers: {'Content-Type': 'application/json'}})
+export const userRegister = (registerInfo: RegisterInfo) => {
+    return axios.post(`${USER_MODULE}/register`, registerInfo,
+        {headers: {'Content-Type': 'application/json'}})
         .then(res => {
             return res
         })
@@ -27,8 +48,8 @@ export const userInfo = () => {
 }
 
 // 更新用户信息
-export const userInfoUpdate = payload => {
-    return axios.post(`${USER_MODULE}`, payload, {headers: {'Content-Type': 'application/json'}})
+export const userInfoUpdate = (updateInfo: UpdateInfo) => {
+    return axios.post(`${USER_MODULE}`, updateInfo, {headers: {'Content-Type': 'application/json'}})
         .then(res => {
             return res
         })

+ 27 - 27
src/components/OrderItem.vue

@@ -40,19 +40,19 @@ getOrderDetail()
 
 function getOrderDetail() {
   getOrderById(props.orderId).then(res => {
-    userId.value = res.result.userId
-    productId.value = res.result.productId
-    productName.value = res.result.productName
-    amount.value = res.result.amount
-    price.value = res.result.price
-    paid.value = res.result.paid
-    type.value = res.result.type
-    content.value = res.result.content
-    rating.value = res.result.rating
-    status.value = res.result.status
-    createTime.value = res.result.createTime
-    finishTime.value = res.result.finishTime
-    storeId.value = res.result.storeId
+    userId.value = res.data.result.userId
+    productId.value = res.data.result.productId
+    productName.value = res.data.result.productName
+    amount.value = res.data.result.amount
+    price.value = res.data.result.price
+    paid.value = res.data.result.paid
+    type.value = res.data.result.type
+    content.value = res.data.result.content
+    rating.value = res.data.result.rating
+    status.value = res.data.result.status
+    createTime.value = res.data.result.createTime
+    finishTime.value = res.data.result.finishTime
+    storeId.value = res.data.result.storeId
 
     totalPrice.value = amount.value * price.value
     discountPrice.value = totalPrice.value
@@ -69,7 +69,7 @@ const refreshButtonVisible = ref(false)
 
 function handleConfirmOrder() {
   payOrder(props.orderId, couponId.value).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '订单提交成功!',
         type: 'success',
@@ -78,11 +78,11 @@ function handleConfirmOrder() {
       isLoading.value = true
       refreshButtonVisible.value = true
       const paymentWindow = window.open('', '_blank');
-      paymentWindow.document.write(res.result);
+      paymentWindow.document.write(res.data.result);
       paymentWindow.document.forms[0].submit(); // 提交表单
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })
@@ -103,16 +103,16 @@ function handlePayDialogClose() {
 
 function handleDeliver() {
   deliverOrder(props.orderId).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '订单发货成功!',
         type: 'success',
         center: true,
       })
       getOrderDetail()
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })
@@ -122,16 +122,16 @@ function handleDeliver() {
 
 function handleGet() {
   getOrder(props.orderId).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '订单收货成功!',
         type: 'success',
         center: true,
       })
       getOrderDetail()
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })
@@ -152,7 +152,7 @@ function handleSendComment() {
   }
 
   commentOrder(payload).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '评价成功!',
         type: 'success',
@@ -162,7 +162,7 @@ function handleSendComment() {
       commentDialogVisible.value = false
     } else {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })
@@ -185,7 +185,7 @@ const singleTableRef = ref<InstanceType<typeof ElTable>>()
 
 function getAvailableCouponList() {
   getAvailableCouponsByStoreId(storeId.value).then(res => {
-    availableCouponList.value = res.result
+    availableCouponList.value = res.data.result
   })
 }
 
@@ -197,7 +197,7 @@ const handleCurrentChange = (val: Coupon | undefined) => {
   }
   currentRow.value = val
   calculateOrder(props.orderId, couponId.value).then(res => {
-    discountPrice.value = res.result
+    discountPrice.value = res.data.result
   })
 }
 

+ 9 - 9
src/components/ProductItem.vue

@@ -22,15 +22,15 @@ const price = ref()
 const photoUrl = ref('')
 
 getProductById(props.productId).then(res => {
-  storeId.value = res.result.storeId
-  name.value = res.result.name
-  photoUrlList.value = res.result.photoUrlList
-  rating.value = res.result.rating
-  number.value = res.result.number
-  salesAmount.value = res.result.salesAmount
-  stock.value = res.result.stock
-  category.value = res.result.category
-  price.value = res.result.price
+  storeId.value = res.data.result.storeId
+  name.value = res.data.result.name
+  photoUrlList.value = res.data.result.photoUrlList
+  rating.value = res.data.result.rating
+  number.value = res.data.result.number
+  salesAmount.value = res.data.result.salesAmount
+  stock.value = res.data.result.stock
+  category.value = res.data.result.category
+  price.value = res.data.result.price
 
   photoUrl.value = photoUrlList.value[0]
 })

+ 5 - 5
src/components/StoreItem.vue

@@ -17,11 +17,11 @@ const number = ref(0)
 const location = ref('')
 
 getStoreById(props.storeId).then(res => {
-  name.value = res.result.name
-  logoUrl.value = res.result.logoUrl
-  rating.value = res.result.rating
-  number.value = res.result.number
-  location.value = res.result.location
+  name.value = res.data.result.name
+  logoUrl.value = res.data.result.logoUrl
+  rating.value = res.data.result.rating
+  number.value = res.data.result.number
+  location.value = res.data.result.location
 })
 </script>
 

+ 6 - 2
src/router/index.ts

@@ -1,7 +1,7 @@
-import {createRouter, createWebHistory} from "vue-router";
+import {createRouter, createWebHashHistory} from "vue-router";
 
 const router = createRouter({
-    history: createWebHistory(),
+    history: createWebHashHistory(),
     routes: [{
         path: '/',
         redirect: '/login',
@@ -99,6 +99,10 @@ router.beforeEach((to, _, next) => {
     const token:string|null = sessionStorage.getItem('token');
     const role:string|null = sessionStorage.getItem('role')
 
+    if (to.meta.title) {
+        document.title = to.meta.title;
+    }
+
     if (token) {
         if(to.meta.permission) {
             if(to.meta.permission.includes(role!)) {

+ 3 - 5
src/utils/request.ts

@@ -1,8 +1,6 @@
 import axios from 'axios';
 
-const service = axios.create({
-    baseURL: 'http://localhost:8080'
-});
+const service = axios.create();
 
 function hasToken() {
     return !(sessionStorage.getItem('token') == '')
@@ -24,9 +22,9 @@ service.interceptors.request.use(
 service.interceptors.response.use(
     response => {
         if (response.status === 200) {
-            return response.data;
+            return response;
         } else {
-            Promise.reject();
+            return Promise.reject();
         }
     },
     error => {

+ 9 - 9
src/views/coupon/AllCoupon.vue

@@ -13,7 +13,7 @@ const rest = ref('')
 const storeName = ref()
 
 userInfo().then(res => {
-  storeName.value = res.result.storeName
+  storeName.value = res.data.result.storeName
 })
 
 const hasTypeInput = computed(() => type.value != null)
@@ -54,7 +54,7 @@ function handleCreateCoupon() {
   }
   couponDialogVisible.value = false
   createCoupons(payload).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '创建优惠券成功!',
         type: 'success',
@@ -65,9 +65,9 @@ function handleCreateCoupon() {
       satisfaction.value = null
       minus.value = null
       rest.value = null
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })
@@ -76,11 +76,11 @@ function handleCreateCoupon() {
 }
 
 getCoupons().then(res => {
-  myCouponList.value = res.result
+  myCouponList.value = res.data.result
 })
 
 getCouponGroups().then(res => {
-  receiveCouponList.value = res.result
+  receiveCouponList.value = res.data.result
 })
 
 function parseType(type) {
@@ -101,7 +101,7 @@ function parseNull(value) {
 
 function receiveCoupon(couponGroupId) {
   receiveCouponGroup(couponGroupId).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '获取优惠券成功!',
         type: 'success',
@@ -109,9 +109,9 @@ function receiveCoupon(couponGroupId) {
       })
       getMyCouponList()
       getReceiveCouponList()
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })

+ 2 - 2
src/views/order/AllOrder.vue

@@ -10,11 +10,11 @@ const orderList = ref()
 const excelUrl = ref('')
 
 getAllOrder().then(res => {
-  orderList.value = res.result
+  orderList.value = res.data.result
 })
 
 getExcelUrl().then(res => {
-  excelUrl.value = res.result
+  excelUrl.value = res.data.result
 })
 </script>
 

+ 4 - 4
src/views/product/CreateProduct.vue

@@ -30,7 +30,7 @@ function handleCreateProduct() {
     photoUrlList: photoUrlList.value
   };
   createProduct(payload).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '添加商品成功!',
         type: 'success',
@@ -41,9 +41,9 @@ function handleCreateProduct() {
       price.value = '';
       photoUrlList.value = [];
       imageFileList.value = [];
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })
@@ -56,7 +56,7 @@ function handleChange(file, fileList) {
   let formData = new FormData();
   formData.append('file', file.raw);
   uploadImage(formData).then(res => {
-    photoUrlList.value.push(res.result);
+    photoUrlList.value.push(res.data.result);
   });
 }
 

+ 13 - 13
src/views/product/ProductDetail.vue

@@ -50,14 +50,14 @@ const addStockDisabled = computed(() => {
 const commentList = ref([])
 
 getCommentsById(productId).then(res => {
-  commentList.value = res.result
+  commentList.value = res.data.result
 })
 
 getProductDetail()
 
 function getProductDetail() {
   getProductById(productId).then(res => {
-    productVO.value = res.result
+    productVO.value = res.data.result
     storeId.value = productVO.value.storeId
     name.value = productVO.value.name
     photoUrlList.value = productVO.value.photoUrlList
@@ -75,7 +75,7 @@ function getProductDetail() {
 // 添加库存按钮
 function AddStock() {
   addStock(productId, addStockNumber.value).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '添加库存成功!',
         type: 'success',
@@ -83,9 +83,9 @@ function AddStock() {
       })
       addStockNumber.value = null
       getProductDetail()
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })
@@ -101,19 +101,19 @@ function handleCreateOrder() {
     type: type.value
   }
   createOrder(payload).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '创建订单成功!',
         type: 'success',
         center: true,
       })
       getAvailableCouponList()
-      orderId.value = res.result.id
+      orderId.value = res.data.result.id
       orderDialogVisible.value = true
       discountPrice.value = totalPrice.value
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })
@@ -128,7 +128,7 @@ const refreshButtonVisible = ref(false)
 // 确定订单按钮
 function handleConfirmOrder() {
   payOrder(orderId.value, couponId.value).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '订单提交成功!',
         type: 'success',
@@ -137,12 +137,12 @@ function handleConfirmOrder() {
       isLoading.value = true
       refreshButtonVisible.value = true
       const paymentWindow = window.open('', '_blank')
-      paymentWindow.document.write(res.result)
+      paymentWindow.document.write(res.data.result)
       paymentWindow.document.forms[0].submit() // 提交表单
       showForm.value = false // 隐藏表单
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })

+ 1 - 1
src/views/store/AllStore.vue

@@ -10,7 +10,7 @@ const storeList = ref()
 
 // 获取商店列表
 getAllStore().then(res => {
-  storeList.value = res.result
+  storeList.value = res.data.result
 })
 
 // 点击创建商店按钮,跳转到创建商店界面

+ 4 - 4
src/views/store/CreateStore.vue

@@ -26,7 +26,7 @@ function handleCreateStore() {
     logoUrl: logoUrl.value
   };
   createStore(payload).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: '添加商户成功!',
         type: 'success',
@@ -36,9 +36,9 @@ function handleCreateStore() {
       location.value = ''
       logoUrl.value = ''
       imageFileList.value.splice(0)
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })
@@ -51,7 +51,7 @@ function handleChange(file, fileList) {
   let formData = new FormData()
   formData.append('file', file.raw)
   uploadImage(formData).then(res => {
-    logoUrl.value = res.result
+    logoUrl.value = res.data.result
   })
 }
 

+ 2 - 2
src/views/store/StoreDetail.vue

@@ -18,7 +18,7 @@ const location = ref('')
 const productList = ref()
 
 getStoreById(storeId).then(res => {
-  storeVO.value = res.result
+  storeVO.value = res.data.result
   name.value = storeVO.value.name
   logoUrl.value = storeVO.value.logoUrl
   rating.value = storeVO.value.rating
@@ -27,7 +27,7 @@ getStoreById(storeId).then(res => {
 })
 
 getProductsByStoreId(storeId).then(res => {
-  productList.value = res.result
+  productList.value = res.data.result
 })
 
 function toCreateProductPage() {

+ 9 - 9
src/views/user/Dashboard.vue

@@ -26,11 +26,11 @@ getUserInfo()
 
 function getUserInfo() {
   userInfo().then(res => {
-    name.value = res.result.name
-    tel.value = res.result.phone
-    storeName.value = res.result.storeName
-    address.value = res.result.address
-    regTime.value = parseTime(res.result.createTime)
+    name.value = res.data.result.name
+    tel.value = res.data.result.phone
+    storeName.value = res.data.result.storeName
+    address.value = res.data.result.address
+    regTime.value = parseTime(res.data.result.createTime)
 
     newName.value = name.value
   })
@@ -44,14 +44,14 @@ function updateInfo() {
   }
 
   userInfoUpdate(payload).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         customClass: 'customMessage',
         type: 'success',
         message: '更新成功!',
       })
       getUserInfo()
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
         customClass: 'customMessage',
         type: 'error',
@@ -69,7 +69,7 @@ function updatePassword() {
   }
 
   userInfoUpdate(payload).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       password.value = ''
       confirmPassword.value = ''
       ElMessageBox.alert(
@@ -84,7 +84,7 @@ function updatePassword() {
             center: true
 
           }).then(() => router.push({path: "/login"}))
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
         customClass: 'customMessage',
         type: 'error',

+ 6 - 6
src/views/user/Login.vue

@@ -29,23 +29,23 @@ function handleLogin() {
   }
 
   userLogin(payload).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: "登录成功!",
         type: 'success',
         center: true,
       })
-      const token = res.result
+      const token = res.data.result
       sessionStorage.setItem('token', token)
 
       userInfo().then(res => {
-        sessionStorage.setItem('name', res.result.name)
-        sessionStorage.setItem('role', res.result.role)
+        sessionStorage.setItem('name', res.data.result.name)
+        sessionStorage.setItem('role', res.data.result.role)
         router.push({path: "/allStore"})
       })
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })

+ 44 - 5
src/views/user/Register.vue

@@ -2,6 +2,14 @@
 import {ref, computed} from 'vue'
 import {router} from '../../router'
 import {userRegister} from "../../api/user.ts"
+import {getAllStore} from "../../api/store.ts";
+
+
+const storeList = ref({})
+
+getAllStore().then(res => {
+  storeList.value = res.data.result
+})
 
 // 输入框值(需要在前端拦截不合法输入:是否为空+额外规则)
 const name = ref('')
@@ -10,6 +18,7 @@ const tel = ref('')
 const address = ref('')
 const password = ref('')
 const confirmPassword = ref('')
+const storeId = ref(null)
 
 // 电话号码是否为空
 const hasTelInput = computed(() => tel.value != '')
@@ -40,20 +49,21 @@ function handleRegister() {
     phone: tel.value,
     password: password.value,
     address: address.value,
-    createTime: new Date().getTime()
+    createTime: new Date().getTime(),
+    storeId: storeId.value,
   }
 
   userRegister(payload).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: "注册成功!请登录账号",
         type: 'success',
         center: true,
       })
       router.push({path: "/login"})
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })
@@ -119,7 +129,19 @@ function handleRegister() {
 
             <el-col :span="1"></el-col>
 
-            <el-col :span="15">
+
+            <el-col :span="15" v-if="identity!=='STAFF'">
+              <el-form-item>
+                <label for="address">
+                  地址
+                </label>
+                <el-input id="address"
+                          v-model="address"
+                          placeholder="请输入地址"/>
+              </el-form-item>
+            </el-col>
+
+            <el-col :span="7" v-if="identity==='STAFF'">
               <el-form-item>
                 <label for="address">
                   地址
@@ -129,6 +151,23 @@ function handleRegister() {
                           placeholder="请输入地址"/>
               </el-form-item>
             </el-col>
+
+            <el-col :span="1" v-if="identity==='STAFF'"></el-col>
+
+            <el-col :span="7" v-if="identity==='STAFF'">
+              <el-form-item>
+                <label for="address">
+                  所属商店
+                </label>
+                <el-select id="identity"
+                           v-model="storeId"
+                           placeholder="请选择"
+                           style="width: 100%;"
+                >
+                  <el-option v-for="item in storeList" :key="item.id" :label="item.name" :value="item.id"/>
+                </el-select>
+              </el-form-item>
+            </el-col>
           </el-row>
 
           <el-form-item>

+ 0 - 16
tailwind.config.ts

@@ -1,16 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-export default {
-  content: [
-      './src/**/*.{vue,js,ts,jsx,tsx}',
-      "./index.html",
-  ],
-  theme: {
-      extend: {
-          colors: {
-              primary: {"50":"#eff6ff","100":"#dbeafe","200":"#bfdbfe","300":"#93c5fd","400":"#60a5fa","500":"#3b82f6","600":"#2563eb","700":"#1d4ed8","800":"#1e40af","900":"#1e3a8a","950":"#172554"}
-          }
-      },
-  },
-  plugins: [],
-}
-

+ 1 - 2
vite.config.ts

@@ -16,10 +16,9 @@ export default defineConfig({
         Components({
             resolvers: [ElementPlusResolver()],
         })],
-    devServer: {
+    server: {
         port: 3000,
         open: true,
-        hot: true,//自动保存
     },
 
 })