浏览代码

fix: util

furffico 1 年之前
父节点
当前提交
0e4cbfce31

+ 97 - 89
src/avue/form/prodinfo.ts

@@ -20,7 +20,7 @@ const number_input_props = (message: string, precision: number = 0, nonzero: boo
   }
 }
 
-const radio_prop = (label: string, prop: string, options: string[]) => {
+const radio_prop = (label: string, prop: string, options: string[], etc?: object) => {
   return {
     label,
     prop,
@@ -41,95 +41,103 @@ const radio_prop = (label: string, prop: string, options: string[]) => {
   }
 }
 
-export default (parent: any) => {
-  return {
-    column: [
-      {
-        label: '产品名称',
-        prop: 'name',
-        type: 'input',
-        span: 12,
-        row: true,
-        rules: [{
-          required: true,
-          message: "请输入产品名称",
-        }]
-      }, {
-        label: '产品描述',
-        prop: 'desc',
-        type: 'textarea',
-        minRows: 3,
-        maxRows: 5,
-        row: true,
-      }, {
-        label: "价格(¥)",
-        prop: "price",
-        ...number_input_props("请输入产品价格", 2, true),
+export default {
+  labelWidth: 100,
+  column: [
+    {
+      label: '',
+      type: "title",
+      prop: 'title',
+      row: true,
+      labelWidth: 0,
+    },
+    {
+      label: '产品名称',
+      prop: 'name',
+      type: 'input',
+      span: 12,
+      row: true,
+      rules: [{
+        required: true,
+        message: "请输入产品名称",
+      }]
+    }, {
+      label: '产品描述',
+      prop: 'desc',
+      type: 'textarea',
+      minRows: 3,
+      maxRows: 5,
+      row: true,
+    }, {
+      label: "价格(¥)",
+      prop: "price",
+      ...number_input_props("请输入产品价格", 2, true),
+      row: true,
 
+    }, {
+      label: "运费(¥)",
+      ...number_input_props("请输入运费价格", 2),
+      prop: "deliverPrice",
+      row: true,
+    }, {
+      label: "库存(件)",
+      prop: "stockAmount",
+      ...number_input_props("请输入库存数"),
+      row: true,
+    },
+    radio_prop("展示平台", "platform", ["全部", "商城", "直播间"]),
+    {
+      ...radio_prop("商品类型", "kind", ["自营", "第三方链接"]),
+      control: (v: "自营" | "第三方链接") => {
+        return {
+          link: {
+            display: v === '第三方链接'
+          }
+        }
+      }
+    },
+    {
+      label: '第三方链接',
+      prop: 'link',
+      span: 18,
+      row: true,
+      rules: [{
+        required: true,
+        message: "第三方链接 为必填项",
+        trigger: 'blur'
+      }]
+    }, {
+      label: '需要地址',
+      prop: 'needAddr',
+      type: 'switch',
+      dicData: [{
+        label: '否',
+        value: false
       }, {
-        label: "运费(¥)",
-        ...number_input_props("请输入运费价格", 2),
-        prop: "deliverPrice",
-        row: true,
-      }, {
-        label: "库存(件)",
-        prop: "stockAmount",
-        ...number_input_props("请输入库存数"),
-        row: true,
+        label: '是',
+        value: true
+      }],
+      value: true,
+    }, {
+      label: "商品分类",
+      prop: "goodsTypeList",
+      formslot: true,
+      span: 24,
+      row: true,
+    }, {
+      label: '封面图片',
+      prop: 'cover',
+      type: 'upload',
+      listType: 'picture-card',
+      span: 24,
+      accept: 'image/png, image/jpeg',
+      limit: 1,
+      fileSize: 5 * 1024,
+      propsHttp: {
+        res: 'data'
       },
-      radio_prop("展示平台", "platform", ["全部", "商城", "直播间"]),
-      radio_prop("商品类型", "kind", ["自营", "第三方链接"]),
-      {
-        label: '第三方链接',
-        prop: 'link',
-        span: 18,
-        row: true,
-        rules: [{
-          validator: (_: any, v: string, callback: Function) => {
-            console.log(this)
-            // @ts-ignore
-            const selected_kind = parent.form.kind
-            if (selected_kind === '第三方链接' && !v) { // 商品类型为第三方链接,且没有填写链接时验证不通过
-              callback(new Error("商品类型为“第三方链接”时此项必填"))
-            } else {
-              callback()
-            }
-          },
-          trigger: 'blur'
-        }]
-      }, {
-        label: '需要地址',
-        prop: 'needAddr',
-        type: 'switch',
-        dicData: [{
-          label: '否',
-          value: false
-        }, {
-          label: '是',
-          value: true
-        }],
-        value: true,
-      }, {
-        label: "商品分类",
-        prop: "goodsTypeList",
-        formslot: true,
-        span: 24,
-        row: true,
-      }, {
-        label: '封面图片',
-        prop: 'cover',
-        type: 'upload',
-        listType: 'picture-card',
-        span: 24,
-        accept: 'image/png, image/jpeg',
-        limit: 1,
-        fileSize: 5 * 1024,
-        propsHttp: {
-          res: 'data'
-        },
-        tip: '只能上传jpg/png图片,且不超过5MiB(暂时没用)',
-        action: ''
-      }
-    ]
-  }
+      tip: '只能上传jpg/png图片,且不超过5MiB(暂时没用)',
+      action: ''
+    }
+  ]
 }

+ 0 - 215
src/components/transfer-box/index.vue

@@ -1,215 +0,0 @@
-<template>
-  <div class="el-transfer">
-    <transfer-panel v-bind="$props" ref="leftPanel" :data="sourceData" :title="titles[0] || t('el.transfer.titles.0')"
-      :default-checked="leftDefaultChecked" :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')"
-      @checked-change="onSourceCheckedChange">
-      <slot name="left-footer"></slot>
-    </transfer-panel>
-    <div class="el-transfer__buttons">
-      <el-button type="primary" :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
-        @click.native="addToLeft" :disabled="rightChecked.length === 0">
-        <i class="el-icon-arrow-left"></i>
-        <span v-if="buttonTexts[0] !== undefined">{{ buttonTexts[0] }}</span>
-      </el-button>
-      <el-button type="primary" :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
-        @click.native="addToRight" :disabled="leftChecked.length === 0">
-        <span v-if="buttonTexts[1] !== undefined">{{ buttonTexts[1] }}</span>
-        <i class="el-icon-arrow-right"></i>
-      </el-button>
-    </div>
-    <transfer-panel v-bind="$props" ref="rightPanel" :data="targetData" :title="titles[1] || t('el.transfer.titles.1')"
-      :default-checked="rightDefaultChecked" :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')"
-      @checked-change="onTargetCheckedChange">
-      <slot name="right-footer"></slot>
-    </transfer-panel>
-  </div>
-</template>
-
-<script>
-import ElButton from 'element-ui/packages/button';
-import Emitter from 'element-ui/src/mixins/emitter';
-import Locale from 'element-ui/src/mixins/locale';
-import TransferPanel from './transfer-panel.vue';
-import Migrating from 'element-ui/src/mixins/migrating';
-
-export default {
-  name: 'ElTransfer',
-
-  mixins: [Emitter, Locale, Migrating],
-
-  components: {
-    TransferPanel,
-    ElButton
-  },
-
-  props: {
-    data: {
-      type: Array,
-      default() {
-        return [];
-      }
-    },
-    titles: {
-      type: Array,
-      default() {
-        return [];
-      }
-    },
-    buttonTexts: {
-      type: Array,
-      default() {
-        return [];
-      }
-    },
-    filterPlaceholder: {
-      type: String,
-      default: ''
-    },
-    filterMethod: Function,
-    leftDefaultChecked: {
-      type: Array,
-      default() {
-        return [];
-      }
-    },
-    rightDefaultChecked: {
-      type: Array,
-      default() {
-        return [];
-      }
-    },
-    renderContent: Function,
-    value: {
-      type: Array,
-      default() {
-        return [];
-      }
-    },
-    format: {
-      type: Object,
-      default() {
-        return {};
-      }
-    },
-    filterable: Boolean,
-    props: {
-      type: Object,
-      default() {
-        return {
-          label: 'label',
-          key: 'key',
-          disabled: 'disabled'
-        };
-      }
-    },
-    targetOrder: {
-      type: String,
-      default: 'original'
-    }
-  },
-
-  data() {
-    return {
-      leftChecked: [],
-      rightChecked: []
-    };
-  },
-
-  computed: {
-    dataObj() {
-      const key = this.props.key;
-      return this.data.reduce((o, cur) => (o[cur[key]] = cur) && o, {});
-    },
-
-    sourceData() {
-      return this.data.filter(item => this.value.indexOf(item[this.props.key]) === -1);
-    },
-
-    targetData() {
-      if (this.targetOrder === 'original') {
-        return this.data.filter(item => this.value.indexOf(item[this.props.key]) > -1);
-      } else {
-        return this.value.reduce((arr, cur) => {
-          const val = this.dataObj[cur];
-          if (val) {
-            arr.push(val);
-          }
-          return arr;
-        }, []);
-      }
-    },
-
-    hasButtonTexts() {
-      return this.buttonTexts.length === 2;
-    }
-  },
-
-  watch: {
-    value(val) {
-      this.dispatch('ElFormItem', 'el.form.change', val);
-    }
-  },
-
-  methods: {
-    getMigratingConfig() {
-      return {
-        props: {
-          'footer-format': 'footer-format is renamed to format.'
-        }
-      };
-    },
-
-    onSourceCheckedChange(val, movedKeys) {
-      this.leftChecked = val;
-      if (movedKeys === undefined) return;
-      this.$emit('left-check-change', val, movedKeys);
-    },
-
-    onTargetCheckedChange(val, movedKeys) {
-      this.rightChecked = val;
-      if (movedKeys === undefined) return;
-      this.$emit('right-check-change', val, movedKeys);
-    },
-
-    addToLeft() {
-      let currentValue = this.value.slice();
-      this.rightChecked.forEach(item => {
-        const index = currentValue.indexOf(item);
-        if (index > -1) {
-          currentValue.splice(index, 1);
-        }
-      });
-      this.$emit('input', currentValue);
-      this.$emit('change', currentValue, 'left', this.rightChecked);
-    },
-
-    addToRight() {
-      let currentValue = this.value.slice();
-      const itemsToBeMoved = [];
-      const key = this.props.key;
-      this.data.forEach(item => {
-        const itemKey = item[key];
-        if (
-          this.leftChecked.indexOf(itemKey) > -1 &&
-          this.value.indexOf(itemKey) === -1
-        ) {
-          itemsToBeMoved.push(itemKey);
-        }
-      });
-      currentValue = this.targetOrder === 'unshift'
-        ? itemsToBeMoved.concat(currentValue)
-        : currentValue.concat(itemsToBeMoved);
-      this.$emit('input', currentValue);
-      this.$emit('change', currentValue, 'right', this.leftChecked);
-    },
-
-    clearQuery(which) {
-      if (which === 'left') {
-        this.$refs.leftPanel.query = '';
-      } else if (which === 'right') {
-        this.$refs.rightPanel.query = '';
-      }
-    }
-  }
-};
-</script>

+ 0 - 228
src/components/transfer-box/transfer-panel.vue

@@ -1,228 +0,0 @@
-<template>
-  <div class="el-transfer-panel">
-    <p class="el-transfer-panel__header">
-      <el-checkbox v-model="allChecked" @change="handleAllCheckedChange" :indeterminate="isIndeterminate">
-        {{ title }}
-        <span>{{ checkedSummary }}</span>
-      </el-checkbox>
-    </p>
-
-    <div :class="['el-transfer-panel__body', hasFooter ? 'is-with-footer' : '']">
-      <el-input class="el-transfer-panel__filter" v-model="query" size="small" :placeholder="placeholder"
-        @mouseenter.native="inputHover = true" @mouseleave.native="inputHover = false" v-if="filterable">
-        <i slot="prefix" :class="['el-input__icon', 'el-icon-' + inputIcon]" @click="clearQuery"></i>
-      </el-input>
-      <el-checkbox-group v-model="checked" v-show="!hasNoMatch && data.length > 0"
-        :class="{ 'is-filterable': filterable }" class="el-transfer-panel__list">
-        <el-checkbox class="el-transfer-panel__item" :label="item[keyProp]" :disabled="item[disabledProp]"
-          :key="item[keyProp]" v-for="item in filteredData">
-          <option-content :option="item"></option-content>
-        </el-checkbox>
-      </el-checkbox-group>
-      <p class="el-transfer-panel__empty" v-show="hasNoMatch">{{ t('el.transfer.noMatch') }}</p>
-      <p class="el-transfer-panel__empty" v-show="data.length === 0 && !hasNoMatch">{{ t('el.transfer.noData') }}</p>
-    </div>
-    <p class="el-transfer-panel__footer" v-if="hasFooter">
-      <slot></slot>
-    </p>
-  </div>
-</template>
-
-<script>
-import ElCheckboxGroup from 'element-ui/packages/checkbox-group';
-import ElCheckbox from 'element-ui/packages/checkbox';
-import ElInput from 'element-ui/packages/input';
-import Locale from 'element-ui/src/mixins/locale';
-
-export default {
-  mixins: [Locale],
-
-  name: 'ElTransferPanel',
-
-  componentName: 'ElTransferPanel',
-
-  components: {
-    ElCheckboxGroup,
-    ElCheckbox,
-    ElInput,
-    OptionContent: {
-      props: {
-        option: Object
-      },
-      render(h) {
-        const getParent = vm => {
-          if (vm.$options.componentName === 'ElTransferPanel') {
-            return vm;
-          } else if (vm.$parent) {
-            return getParent(vm.$parent);
-          } else {
-            return vm;
-          }
-        };
-        const panel = getParent(this);
-        const transfer = panel.$parent || panel;
-        return panel.renderContent
-          ? panel.renderContent(h, this.option)
-          : transfer.$scopedSlots.default
-            ? transfer.$scopedSlots.default({ option: this.option })
-            : <span>{this.option[panel.labelProp] || this.option[panel.keyProp]}</span>;
-      }
-    }
-  },
-
-  props: {
-    data: {
-      type: Array,
-      default() {
-        return [];
-      }
-    },
-    renderContent: Function,
-    placeholder: String,
-    title: String,
-    filterable: Boolean,
-    format: Object,
-    filterMethod: Function,
-    defaultChecked: Array,
-    props: Object
-  },
-
-  data() {
-    return {
-      checked: [],
-      allChecked: false,
-      query: '',
-      inputHover: false,
-      checkChangeByUser: true
-    };
-  },
-
-  watch: {
-    checked(val, oldVal) {
-      this.updateAllChecked();
-      if (this.checkChangeByUser) {
-        const movedKeys = val.concat(oldVal)
-          .filter(v => val.indexOf(v) === -1 || oldVal.indexOf(v) === -1);
-        this.$emit('checked-change', val, movedKeys);
-      } else {
-        this.$emit('checked-change', val);
-        this.checkChangeByUser = true;
-      }
-    },
-
-    data() {
-      const checked = [];
-      const filteredDataKeys = this.filteredData.map(item => item[this.keyProp]);
-      this.checked.forEach(item => {
-        if (filteredDataKeys.indexOf(item) > -1) {
-          checked.push(item);
-        }
-      });
-      this.checkChangeByUser = false;
-      this.checked = checked;
-    },
-
-    checkableData() {
-      this.updateAllChecked();
-    },
-
-    defaultChecked: {
-      immediate: true,
-      handler(val, oldVal) {
-        if (oldVal && val.length === oldVal.length &&
-          val.every(item => oldVal.indexOf(item) > -1)) return;
-        const checked = [];
-        const checkableDataKeys = this.checkableData.map(item => item[this.keyProp]);
-        val.forEach(item => {
-          if (checkableDataKeys.indexOf(item) > -1) {
-            checked.push(item);
-          }
-        });
-        this.checkChangeByUser = false;
-        this.checked = checked;
-      }
-    }
-  },
-
-  computed: {
-    filteredData() {
-      return this.data.filter(item => {
-        if (typeof this.filterMethod === 'function') {
-          return this.filterMethod(this.query, item);
-        } else {
-          const label = item[this.labelProp] || item[this.keyProp].toString();
-          return label.toLowerCase().indexOf(this.query.toLowerCase()) > -1;
-        }
-      });
-    },
-
-    checkableData() {
-      return this.filteredData.filter(item => !item[this.disabledProp]);
-    },
-
-    checkedSummary() {
-      const checkedLength = this.checked.length;
-      const dataLength = this.data.length;
-      const { noChecked, hasChecked } = this.format;
-      if (noChecked && hasChecked) {
-        return checkedLength > 0
-          ? hasChecked.replace(/\${checked}/g, checkedLength).replace(/\${total}/g, dataLength)
-          : noChecked.replace(/\${total}/g, dataLength);
-      } else {
-        return `${checkedLength}/${dataLength}`;
-      }
-    },
-
-    isIndeterminate() {
-      const checkedLength = this.checked.length;
-      return checkedLength > 0 && checkedLength < this.checkableData.length;
-    },
-
-    hasNoMatch() {
-      return this.query.length > 0 && this.filteredData.length === 0;
-    },
-
-    inputIcon() {
-      return this.query.length > 0 && this.inputHover
-        ? 'circle-close'
-        : 'search';
-    },
-
-    labelProp() {
-      return this.props.label || 'label';
-    },
-
-    keyProp() {
-      return this.props.key || 'key';
-    },
-
-    disabledProp() {
-      return this.props.disabled || 'disabled';
-    },
-
-    hasFooter() {
-      return !!this.$slots.default;
-    }
-  },
-
-  methods: {
-    updateAllChecked() {
-      const checkableDataKeys = this.checkableData.map(item => item[this.keyProp]);
-      this.allChecked = checkableDataKeys.length > 0 &&
-        checkableDataKeys.every(item => this.checked.indexOf(item) > -1);
-    },
-
-    handleAllCheckedChange(value) {
-      this.checked = value
-        ? this.checkableData.map(item => item[this.keyProp])
-        : [];
-    },
-
-    clearQuery() {
-      if (this.inputIcon === 'circle-close') {
-        this.query = '';
-      }
-    }
-  }
-};
-</script>

+ 0 - 0
src/element-ui/index.js → src/element-ui.js


+ 2 - 1
src/main.ts

@@ -11,9 +11,10 @@ import '@smallwei/avue/lib/index.css'
 import '@/assets/scss/index.scss'
 import httpRequest from '@/utils/httpRequest' // api: https://github.com/axios/axios
 import { isAuth } from '@/utils'
+import axios from 'axios'
 // import cloneDeep from 'lodash/cloneDeep'
 
-Vue.use(Avue)
+Vue.use(Avue, { axios })
 Vue.use(VueCookie)
 Vue.use(ElementUI)
 Vue.config.productionTip = false

+ 1 - 2
src/shims-vue.d.ts

@@ -4,5 +4,4 @@ declare module '*.vue' {
 }
 
 declare module '@smallwei/avue';
-declare module 'vue-cookie';
-declare module '@/components/transfer-box';
+declare module 'vue-cookie';

+ 3 - 2
src/utils/currency.ts

@@ -1,5 +1,6 @@
 
+export type DatabaseCurrency = number
 // 因为数据库表内价格是以分为单位的整数,因此在展示与请求时需要转换
 // 以下为转换函数
-export const database2real = (n: number) => n / 100
-export const real2database = (n: number) => n * 100
+export const database2real = (n: DatabaseCurrency): number => n / 100
+export const real2database = (n: number): DatabaseCurrency => n * 100

+ 18 - 0
src/utils/vo.ts

@@ -14,6 +14,24 @@ export interface IUser {
   createdAt: string
 }
 
+export interface IProdInfo {
+  id?: number
+  name: string
+  desc: string
+  price: number
+  deliverPrice: number
+  stockAmount: number
+  // soldAmount: number
+  cover: string[]
+  kind: "" | "自营" | "第三方链接"
+  platform: "" | "全部" | "商城" | "直播间"
+  link: string
+  needAddr: boolean
+  goodsTypeList: number[]
+  adminId: number
+  title: string
+}
+
 export type IPage = Record<"total" | "currentPage" | "pageSize", number>
 interface IPageData<T> {
   // 后端返回的格式不统一,这个用不了

+ 1 - 120
src/views/common/home.vue

@@ -1,125 +1,6 @@
 <template>
   <div class="mod-home">
-    <p>一个基于spring boot、spring oauth2.0、mybatis、redis的轻量级、前后端分离、拥有完整sku和下单流程的完全开源商城</p>
-    <p>&nbsp;</p>
-    <p>该项目仅供学习参考、可供个人学习使用、如需商用联系作者进行授权,否则必将追究法律责任</p>
-    <p>&nbsp;</p>
-    <h2>前言</h2>
-    <p>
-      <code>mall4j商城</code>项目致力于为中小企业打造一个完整、易于维护的开源的电商系统,采用现阶段流行技术实现。后台管理系统包含商品管理、订单管理、运费模板、规格管理、会员管理、运营管理、内容管理、统计报表、权限管理、设置等模块。
-    </p>
-    <p>&nbsp;</p>
-    <h2>技术选型</h2>
-    <figure>
-      <table border="1"
-             cellspacing="0"
-             cellpadding="5px">
-        <thead>
-          <tr>
-            <th>技术</th>
-            <th>版本</th>
-            <th>说明</th>
-          </tr>
-        </thead>
-        <tbody>
-          <tr>
-            <td>Spring Boot</td>
-            <td>3.0.4</td>
-            <td>MVC核心框架</td>
-          </tr>
-          <tr>
-            <td>MyBatis</td>
-            <td>3.5.0</td>
-            <td>ORM框架</td>
-          </tr>
-          <tr>
-            <td>MyBatisPlus</td>
-            <td>3.5.3.1</td>
-            <td>基于mybatis,使用lambda表达式的</td>
-          </tr>
-          <tr>
-            <td>Swagger-UI</td>
-            <td>4.0.0</td>
-            <td>文档生产工具</td>
-          </tr>
-          <tr>
-            <td>redisson</td>
-            <td>3.19.3</td>
-            <td>对redis进行封装、集成分布式锁等</td>
-          </tr>
-          <tr>
-            <td>hikari</td>
-            <td>3.2.0</td>
-            <td>数据库连接池</td>
-          </tr>
-          <tr>
-            <td>log4j2</td>
-            <td>2.17.2</td>
-            <td>更快的log日志工具</td>
-          </tr>
-          <tr>
-            <td>lombok</td>
-            <td>1.18.8</td>
-            <td>简化对象封装工具</td>
-          </tr>
-          <tr>
-            <td>hutool</td>
-            <td>5.8.15</td>
-            <td>更适合国人的java工具集</td>
-          </tr>
-          <tr>
-            <td>xxl-job</td>
-            <td>2.3.1</td>
-            <td>定时任务</td>
-          </tr>
-        </tbody>
-      </table>
-    </figure>
-    <p>&nbsp;</p>
-    <h2>部署教程</h2>
-    <p>&nbsp;</p>
-    <h3>1.开发环境</h3>
-    <figure>
-      <table border="1"
-             cellspacing="0"
-             cellpadding="5px">
-        <thead>
-          <tr>
-            <th>工具</th>
-            <th>版本</th>
-          </tr>
-        </thead>
-        <tbody>
-          <tr>
-            <td>jdk</td>
-            <td>17</td>
-          </tr>
-          <tr>
-            <td>mysql</td>
-            <td>5.7+</td>
-          </tr>
-          <tr>
-            <td>redis</td>
-            <td>3.2+</td>
-          </tr>
-        </tbody>
-      </table>
-    </figure>
-    <h3>2.启动</h3>
-    <ul>
-      <li>推荐使用idea,安装lombok插件,使用idea导入maven项目</li>
-      <li>
-        将shop.sql导入到mysql中,修改
-        <code>application-dev.yml</code>更改 datasource.url、user、password
-      </li>
-      <li>启动redis</li>
-      <li>
-        通过
-        <code>WebApplication</code>启动项目后台接口,
-        <code>ApiApplication</code> 启动项目前端接口
-      </li>
-    </ul>
-    <p>&nbsp;</p>
+    首页
   </div>
 </template>
 

+ 23 - 30
src/views/common/login.vue

@@ -2,25 +2,15 @@
   <div class="login">
     <div class="login-box">
       <div class="top">
-        <div class="logo"><img src="~@/assets/img/login-logo.png"
-               alt=""></div>
+        <div class="logo"><img src="@/assets/img/login-logo.png" alt=""></div>
       </div>
       <div class="mid">
-        <el-form :model="dataForm"
-                 :rules="dataRule"
-                 ref="dataForm"
-                 @keyup.enter.native="dataFormSubmit()"
-                 status-icon>
+        <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" status-icon>
           <el-form-item prop="userName">
-            <el-input class="info"
-                      v-model="dataForm.userName"
-                      placeholder="帐号"></el-input>
+            <el-input class="info" v-model="dataForm.userName" placeholder="帐号"></el-input>
           </el-form-item>
           <el-form-item prop="password">
-            <el-input class="info"
-                      v-model="dataForm.password"
-                      type="password"
-                      placeholder="密码"></el-input>
+            <el-input class="info" v-model="dataForm.password" type="password" placeholder="密码"></el-input>
           </el-form-item>
           <!-- <el-form-item prop="captcha">
             <el-row :gutter="20">
@@ -38,21 +28,14 @@
             </el-row>
           </el-form-item> -->
           <el-form-item>
-            <div class="item-btn"><input type="button"
-                     value="登录"
-                     @click="dataFormSubmit()"></div>
+            <div class="item-btn"><input type="button" value="登录" @click="dataFormSubmit()"></div>
           </el-form-item>
         </el-form>
       </div>
 
       <div class="bottom">Copyright © 2019 广州市蓝海创新科技有限公司</div>
     </div>
-    <Verify
-      ref="verify"
-      :captcha-type="'blockPuzzle'"
-      :img-size="{width:'400px',height:'200px'}"
-      @success="login"
-    />
+    <Verify ref="verify" :captcha-type="'blockPuzzle'" :img-size="{ width: '400px', height: '200px' }" @success="login" />
   </div>
 </template>
 
@@ -64,7 +47,7 @@ export default {
   components: {
     Verify
   },
-  data () {
+  data() {
     return {
       dataForm: {
         userName: '',
@@ -86,30 +69,30 @@ export default {
       captchaPath: ''
     }
   },
-  beforeDestroy () {
+  beforeDestroy() {
     document.removeEventListener('keyup', this.handerKeyup)
   },
-  created () {
+  created() {
     this.getCaptcha()
 
     document.addEventListener('keyup', this.handerKeyup)
   },
   methods: {
-    handerKeyup (e) {
+    handerKeyup(e) {
       var keycode = document.all ? event.keyCode : e.which
       if (keycode === 13) {
         this.dataFormSubmit()
       }
     },
     // 提交表单
-    dataFormSubmit () {
+    dataFormSubmit() {
       this.$refs['dataForm'].validate((valid) => {
         if (valid) {
           this.$refs.verify.show()
         }
       })
     },
-    login (verifyResult) {
+    login(verifyResult) {
       if (this.isSubmit) {
         return
       }
@@ -151,7 +134,7 @@ export default {
     //   })
     // },
     // 获取验证码
-    getCaptcha () {
+    getCaptcha() {
       this.dataForm.uuid = getUUID()
       this.captchaPath = this.$http.adornUrl(`/captcha.jpg?uuid=${this.dataForm.uuid}`)
     }
@@ -167,6 +150,7 @@ export default {
   background-size: cover;
   position: fixed;
 }
+
 .login .login-box {
   position: absolute;
   left: 50%;
@@ -174,25 +158,31 @@ export default {
   height: 100%;
   padding-top: 10%;
 }
+
 .login .login-box .top {
   margin-bottom: 30px;
   text-align: center;
 }
+
 .login .login-box .top .logo {
   font-size: 0;
   max-width: 50%;
   margin: 0 auto;
 }
+
 .login .login-box .top .company {
   font-size: 16px;
   margin-top: 10px;
 }
+
 .login .login-box .mid {
   font-size: 14px;
 }
+
 .login .login-box .mid .item-btn {
   margin-top: 20px;
 }
+
 .login .login-box .mid .item-btn input {
   border: 0;
   width: 100%;
@@ -202,12 +192,15 @@ export default {
   color: #fff;
   border-radius: 3px;
 }
+
 .info {
   width: 410px;
 }
+
 .login-captcha {
   height: 40px;
 }
+
 .login .login-box .bottom {
   position: absolute;
   bottom: 10%;

+ 10 - 12
src/views/modules/prod/prodInfo.vue

@@ -11,10 +11,9 @@
 import Vue from 'vue'
 import httpx, { AxiosResponse } from '@/utils/httpx'
 import formOption from "@/avue/form/prodinfo"
-import { ICategory } from '@/utils/vo'
+import { ICategory, IProdInfo } from '@/utils/vo'
 import { isInteger } from 'lodash'
 import { database2real, real2database } from "@/utils/currency"
-// import TransferBox from '@/components/transfer-box'
 
 interface ISelection {
   key: number,
@@ -33,23 +32,21 @@ export default Vue.extend({
         deliverPrice: 0,
         stockAmount: 0,
         // soldAmount: 0,
-        cover: [] as string[],
+        cover: [],
         kind: "",
         platform: "",
         link: "",
         needAddr: true,
-        goodsTypeList: [] as number[],
-        adminId: null,
-      },
-      option: formOption(this),
+        goodsTypeList: [],
+        adminId: 0,
+        title: "新增商品",
+      } as IProdInfo,
+      option: formOption,
       categories: [] as ICategory[],
       new: false,
       id: 0,
     }
   },
-  // components: {
-  //   TransferBox
-  // },
   mounted() {
     this.getCategoryList("")
     const id_str = this.$route.params.id
@@ -63,6 +60,7 @@ export default Vue.extend({
     } else {
       this.new = false
       this.id = id
+      this.form.title = '修改商品'
       httpx.post(
         httpx.makeurl("/goods/editGood"),
         id
@@ -86,6 +84,7 @@ export default Vue.extend({
           needAddr: item.needAddr,
           goodsTypeList: categories,
           adminId: item.adminId,
+          title: `修改商品 ${item.name}`,
         }
       })
     }
@@ -99,8 +98,7 @@ export default Vue.extend({
         this.categories = data.goodsTypeList
       })
     },
-    // @ts-ignore
-    onSubmit(form: typeof this.form, done: Function) {
+    onSubmit(form: IProdInfo, done: Function) {
       console.log(form)
       const path = this.new ? "/goods/addGood" : "/goods/updateGood"
       const id_form: { id?: number } = this.new ? {} : { id: this.id }

+ 1 - 1
vue.config.js

@@ -46,7 +46,7 @@ module.exports = {
     devServer:{
       proxy: {
         // "^/user": {target: "http://192.168.58.137:10086"},
-        "^/(user|goods|goodsTypes|order)/": {target: "http://127.0.0.1:10086"},
+        "^/(user|goods|goodsTypes|order|orderItem)/": {target: "http://127.0.0.1:10086"},
         "^/.*": {target: "http://116.63.32.160:8085"},
       },
     }