ソースを参照

Merge branch 'master' of http://git.ycjcjy.com/zhiyuxing/pc-admin

魏熙美 5 年 前
コミット
e120dcdb77
共有6 個のファイルを変更した246 個の追加34 個の削除を含む
  1. 1
    0
      public/index.html
  2. 59
    9
      src/components/EditableTag.vue
  3. 22
    8
      src/components/RichEditor.vue
  4. 81
    3
      src/views/building/edit.vue
  5. 81
    12
      src/views/exchange/verify.vue
  6. 2
    2
      vue.config.js

+ 1
- 0
public/index.html ファイルの表示

6
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
6
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
7
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
7
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
8
     <link rel="stylesheet" href="//at.alicdn.com/t/font_1070150_8lyiyriedbr.css">
8
     <link rel="stylesheet" href="//at.alicdn.com/t/font_1070150_8lyiyriedbr.css">
9
+    <link rel="stylesheet" href="//at.alicdn.com/t/font_1320815_gazogjls0pk.css">
9
     <title>后台管理系统</title>
10
     <title>后台管理系统</title>
10
   </head>
11
   </head>
11
   <body>
12
   <body>

+ 59
- 9
src/components/EditableTag.vue ファイルの表示

1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
     <el-tag
3
     <el-tag
4
-      :key="item[label]"
5
-      v-for="item in value"
4
+      v-for="item in values"
5
+      :key="item[labelName]"
6
       closable
6
       closable
7
       :disable-transitions="false"
7
       :disable-transitions="false"
8
       @close="() => handleClose(item)">
8
       @close="() => handleClose(item)">
9
-      {{item[label]}}
9
+      {{item[labelName]}}
10
     </el-tag>
10
     </el-tag>
11
     <el-input
11
     <el-input
12
       class="input-new-tag"
12
       class="input-new-tag"
28
     props: [
28
     props: [
29
       'value',
29
       'value',
30
       'label',
30
       'label',
31
+      'soureType', // String, StringArray, ObjectArray, 默认 String
31
     ],
32
     ],
32
     data() {
33
     data() {
33
       return {
34
       return {
34
         inputVisible: false,
35
         inputVisible: false,
35
-        inputValue: ''
36
+        inputValue: '',
37
+        values: [],
38
+        labelName: 'tag',
36
       };
39
       };
37
     },
40
     },
41
+    watch: {
42
+      'label': {
43
+        handler (newVal) {
44
+          if (newVal) {
45
+            this.labelName = newVal
46
+          }
47
+        },
48
+        immediate: true,
49
+      },
50
+      'value': {
51
+        handler (newVal) {
52
+          // 支持 string, [ string ], [ object ] 三种形式
53
+          // 如果是 string 或者 [string] 形式, 则会被转换成 [ { xTagInx, label } ] 格式的数组
54
+          if (this.soureType === 'ObjectArray') {
55
+            this.values = newVal || []
56
+          } else if (this.soureType === 'StringArray') {
57
+            this.values = (newVal || []).map((x, i) => ({ xTagInx: i, [`${this.labelName}`]: x }))
58
+          } else {
59
+            this.values = (newVal || '').split(',').filter(x => x).map((x, i) => ({ xTagInx: i, [`${this.labelName}`]: x }))
60
+          }
61
+        },
62
+        immediate: true,
63
+      },
64
+    },
65
+    created () {
66
+    },
38
     methods: {
67
     methods: {
39
       handleClose(item) {
68
       handleClose(item) {
40
-        this.$confirm(`确认删除 ${item[this.label]}?`, '提示', {
69
+        const target = item[this.labelName]
70
+
71
+        this.$confirm(`确认删除 ${target}?`, '提示', {
41
           confirmButtonText: '确定',
72
           confirmButtonText: '确定',
42
           cancelButtonText: '取消',
73
           cancelButtonText: '取消',
43
           type: 'warning'
74
           type: 'warning'
44
         }).then(() => {
75
         }).then(() => {
45
-          this.$emit('delete', item)
76
+          if (this.soureType === 'ObjectArray') {
77
+            this.$emit('delete', item)
78
+            this.$emit('input', this.values.filter(x => x[this.labelName] != target))
79
+          } else if (this.soureType === 'StringArray') {
80
+            this.$emit('delete', target)
81
+            this.$emit('input', this.values.filter(x => x[this.labelName] != target).map(x => x[this.labelName]))
82
+          } else {
83
+            this.$emit('delete', target)
84
+            this.$emit('input', this.values.filter(x => x[this.labelName] != target).map(x => x[this.labelName]).join(','))
85
+          }
46
         }).catch(() => {})
86
         }).catch(() => {})
47
       },
87
       },
48
-
49
       showInput() {
88
       showInput() {
50
         this.inputVisible = true;
89
         this.inputVisible = true;
51
         this.$nextTick(() => {
90
         this.$nextTick(() => {
54
       },
93
       },
55
 
94
 
56
       handleInputConfirm() {
95
       handleInputConfirm() {
57
-        let inputValue = this.inputValue
96
+        const inputValue = this.inputValue
58
         if (inputValue) {
97
         if (inputValue) {
59
-          this.$emit('insert', inputValue)
98
+          // 输出结果与输入类型一致
99
+          if (this.soureType === 'ObjectArray') {
100
+            const newVal = { [`${this.labelName}`]: inputValue }
101
+            this.$emit('insert', newVal)
102
+            this.$emit('input', (this.value || []).concat(newVal))
103
+          } else if (this.soureType === 'StringArray') {
104
+            this.$emit('insert', inputValue)
105
+            this.$emit('input', (this.value || []).concat(inputValue))
106
+          } else {
107
+            this.$emit('insert', inputValue)
108
+            this.$emit('input', (this.value || '').split(',').filter(x => x).concat(inputValue).join(','))
109
+          }
60
         }
110
         }
61
         this.inputVisible = false
111
         this.inputVisible = false
62
         this.inputValue = ''
112
         this.inputValue = ''

+ 22
- 8
src/components/RichEditor.vue ファイルの表示

19
     }
19
     }
20
   },
20
   },
21
   watch: {
21
   watch: {
22
-    value (newVal) {
23
-      const newTxt = this.getHtmlTxt(newVal)
24
-      const oriTxt = this.getHtmlTxt(this.html)
22
+    'value': {
23
+      handler (newVal) {
24
+        const newTxt = this.getHtmlTxt(newVal)
25
+        const oriTxt = this.getHtmlTxt(this.html)
25
 
26
 
26
-      if (newTxt != oriTxt) {
27
-        this.updateContent(newVal)
28
-        this.initedContent = true
29
-      }
27
+        if (newTxt != oriTxt) {
28
+          this.updateContent(newVal)
29
+          this.initedContent = true
30
+        }
31
+      },
32
+      immediate: true,
30
     }
33
     }
31
   },
34
   },
32
   mounted () {
35
   mounted () {
43
         editor.customConfig = this.setting
46
         editor.customConfig = this.setting
44
       }
47
       }
45
 
48
 
49
+      // 重定义 index
50
+      editor.customConfig.zIndex = 100
51
+
52
+      // 重定义 height
53
+      // 见 style
54
+
46
       // 重新定义图片上传
55
       // 重新定义图片上传
47
       editor.customConfig.customUploadImg = this.uploadImg
56
       editor.customConfig.customUploadImg = this.uploadImg
48
 
57
 
54
       editor.create()
63
       editor.create()
55
 
64
 
56
       if (this.html) {
65
       if (this.html) {
57
-        editor.txt.html(html)
66
+        editor.txt.html(this.html)
58
       }
67
       }
59
     },
68
     },
60
     uploadImg (files, insert) {
69
     uploadImg (files, insert) {
75
 }
84
 }
76
 </script>
85
 </script>
77
 
86
 
87
+<style>
88
+.w-e-text-container {
89
+  height: calc(100% - 52px) !important;
90
+}
91
+</style>

+ 81
- 3
src/views/building/edit.vue ファイルの表示

100
             <el-radio :label="0">否</el-radio>
100
             <el-radio :label="0">否</el-radio>
101
           </el-radio-group>
101
           </el-radio-group>
102
         </el-form-item>
102
         </el-form-item>
103
-        <el-form-item label="项目备注">
104
-          <rich-editor v-model="building.remark" style="height: 400px" />
105
-        </el-form-item>
106
         <el-form-item label="楼盘区域">
103
         <el-form-item label="楼盘区域">
107
           <el-input v-model="building.buildingArea"></el-input>
104
           <el-input v-model="building.buildingArea"></el-input>
108
         </el-form-item>
105
         </el-form-item>
124
             </div>
121
             </div>
125
           </div>  
122
           </div>  
126
         </el-form-item>
123
         </el-form-item>
124
+        <el-form-item label="周边交通">
125
+          <editable-tag v-model="building.buildingTransport" />
126
+        </el-form-item>
127
+        <el-form-item label="周边商业">
128
+          <editable-tag v-model="building.buildingMall" />
129
+        </el-form-item>
130
+        <el-form-item label="周边学校">
131
+          <editable-tag v-model="building.buildingEdu" />
132
+        </el-form-item>
133
+        <el-form-item label="周边医院">
134
+          <editable-tag v-model="building.buildingHospital" />
135
+        </el-form-item>
136
+        <el-form-item label="周边银行">
137
+          <editable-tag v-model="building.buildingBank" />
138
+        </el-form-item>
139
+        <el-form-item label="周边餐饮">
140
+          <editable-tag v-model="building.buildingRestaurant" />
141
+        </el-form-item>
142
+        <el-form-item label="项目类型">
143
+        </el-form-item>
144
+        <el-form-item label="绿化率">
145
+          <el-input v-model="building.greeningRate"></el-input>
146
+        </el-form-item>
147
+        <el-form-item label="容积率">
148
+          <el-input v-model="building.volumeRate"></el-input>
149
+        </el-form-item>
150
+        <el-form-item label="车位比">
151
+          <el-input v-model="building.parkingRate"></el-input>
152
+        </el-form-item>
153
+        <el-form-item label="规划户数">
154
+          <el-input-number v-model="building.familyNum"></el-input-number>
155
+        </el-form-item>
156
+        <el-form-item label="物业公司">
157
+          <el-input v-model="building.serviceCompany"></el-input>
158
+        </el-form-item>
159
+        <el-form-item label="物业费">
160
+          <el-input v-model="building.serviceFee"></el-input>
161
+        </el-form-item>
162
+        <el-form-item label="装修标准">
163
+          <el-input v-model="building.decoration"></el-input>
164
+        </el-form-item>
165
+        <el-form-item label="交房时间">
166
+          <el-date-picker
167
+            v-model="building.receivedDate"
168
+            type="date"
169
+            placeholder="选择日期">
170
+          </el-date-picker>
171
+        </el-form-item>
172
+        <el-form-item label="产权年限">
173
+          <el-input-number v-model="building.rightsYear"></el-input-number>
174
+        </el-form-item>
175
+        <el-form-item label="预售许可证">
176
+          <el-upload
177
+            class="avatar-uploader"
178
+            :action="upFileUrl"
179
+            :headers="uploadHeaders"
180
+            name='file'
181
+            :show-file-list="false"
182
+            :before-upload="beforeImgUpload"
183
+            :on-success="handlePreSalePermitSuccess">
184
+            <img v-if="building.preSalePermit" :src="building.preSalePermit" class="avatar">
185
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
186
+          </el-upload>
187
+        </el-form-item>
188
+        <el-form-item label="项目备注">
189
+          <rich-editor v-model="building.remark" style="height: 400px" />
190
+        </el-form-item>
127
         <el-form-item>
191
         <el-form-item>
128
           <el-button type="primary" @click="onSubmit">保存</el-button>
192
           <el-button type="primary" @click="onSubmit">保存</el-button>
129
           <el-button @click="onCancel">取消</el-button>
193
           <el-button @click="onCancel">取消</el-button>
221
           <el-form-item label="套内面积">
285
           <el-form-item label="套内面积">
222
             <el-input v-model="aparmentInfo.insideArea"></el-input>
286
             <el-input v-model="aparmentInfo.insideArea"></el-input>
223
           </el-form-item>
287
           </el-form-item>
288
+          <el-form-item label="户型总价">
289
+            <el-input v-model="aparmentInfo.apartmentPrice"></el-input>
290
+          </el-form-item>
291
+          <el-form-item label="户型简介">
292
+            <rich-editor v-model="aparmentInfo.apartmentDescription" style="height: 200px"></rich-editor>
293
+          </el-form-item>
224
           <el-form-item label="备注">
294
           <el-form-item label="备注">
225
             <el-input type="textarea" v-model="aparmentInfo.remark"></el-input>
295
             <el-input type="textarea" v-model="aparmentInfo.remark"></el-input>
226
           </el-form-item>
296
           </el-form-item>
243
 const { mapActions: mapApartmentActions } = createNamespacedHelpers('apartment')
313
 const { mapActions: mapApartmentActions } = createNamespacedHelpers('apartment')
244
 
314
 
245
 export default {
315
 export default {
316
+  name: 'BuildingEdit',
317
+  components: {
318
+    EditableTag: () => import('@/components/EditableTag.vue'),
319
+  },
246
   data () {
320
   data () {
247
     var _self = this
321
     var _self = this
248
     return {
322
     return {
391
       this.building = {...this.building, poster: res.data }
465
       this.building = {...this.building, poster: res.data }
392
       this.loading.close()
466
       this.loading.close()
393
     },
467
     },
468
+    handlePreSalePermitSuccess(res) {
469
+      this.building = {...this.building, preSalePermit: res.data }
470
+      this.loading.close()
471
+    },
394
     handleAparmentSuccess (res) {
472
     handleAparmentSuccess (res) {
395
       this.aparmentImg = [...this.aparmentImg, {
473
       this.aparmentImg = [...this.aparmentImg, {
396
         url: res.data
474
         url: res.data

+ 81
- 12
src/views/exchange/verify.vue ファイルの表示

1
 <template>
1
 <template>
2
-<el-tabs type="border-card">
3
-  <el-tab-pane label="扫码核销">用户管理</el-tab-pane>
2
+<el-tabs type="border-card" class="border-card">
3
+  <el-tab-pane label="扫码核销">
4
+    <el-row>
5
+      <el-col :span="8">
6
+        <div class="grid-content">
7
+          <i class="iconfont icon-erweima"></i>
8
+          <p>1</p>
9
+          <p>请用户出示核销的二维码</p>
10
+          <p>请将网页输入法切换成英文</p>
11
+          
12
+        </div>
13
+      </el-col>
14
+      <el-col :span="8">
15
+        <div class="grid-content ">
16
+          <i class="iconfont icon-iconfontscan"></i>
17
+          <p>2</p>
18
+          <p>点击“立即核销”按钮</p>
19
+          <p>使用扫码枪扫描客户二维码</p>
20
+        </div>
21
+      </el-col>
22
+      <el-col :span="8">
23
+        <div class="grid-content">
24
+          <i class="iconfont icon-iconfontzhizuobiaozhun0261"></i>
25
+          <p>3</p>
26
+          <p>根据提示进行核销操作</p>
27
+        </div>
28
+      </el-col>
29
+    </el-row>
30
+    <el-button type="danger" style="margin:20px auto 0 auto;display:block" round>立即核销</el-button>
31
+    
32
+  </el-tab-pane>
4
   <el-tab-pane label="手机号核销">
33
   <el-tab-pane label="手机号核销">
5
-   <el-form :inline="true">
34
+    <el-row>
35
+      <el-col :span="12">
36
+        <div class="grid-content">
37
+          <i class="iconfont icon-erweima"></i>
38
+          <p>1</p>
39
+          <p>请输入用户的手机号</p>
40
+          </div>
41
+      </el-col>
42
+      <el-col :span="12">
43
+        <div class="grid-content">
44
+          <i class="iconfont icon-iconfontzhizuobiaozhun0261"></i>
45
+          <p>2</p>
46
+          <p>点击“立即核销”按钮</p>
47
+        </div>
48
+      </el-col>
49
+    </el-row>
50
+    <el-form :inline="true" style="text-align: center;">
6
       <el-form-item label="">
51
       <el-form-item label="">
7
         <el-input v-model="verifyPhone" placeholder="请输入手机号"></el-input>
52
         <el-input v-model="verifyPhone" placeholder="请输入手机号"></el-input>
8
       </el-form-item>
53
       </el-form-item>
9
       <el-form-item>
54
       <el-form-item>
10
-        <el-button type="primary" @click="verifyTel">立即核销</el-button>
55
+        <el-button type="danger" @click="verifyTel">立即核销</el-button>
11
       </el-form-item>
56
       </el-form-item>
12
     </el-form>
57
     </el-form>
13
   </el-tab-pane>
58
   </el-tab-pane>
16
 
61
 
17
 <script>
62
 <script>
18
 import { createNamespacedHelpers } from "vuex";
63
 import { createNamespacedHelpers } from "vuex";
19
-import dayjs from 'dayjs'
64
+import dayjs from "dayjs";
20
 
65
 
21
 const { mapActions: mapExchangeActions } = createNamespacedHelpers("exchange");
66
 const { mapActions: mapExchangeActions } = createNamespacedHelpers("exchange");
22
 
67
 
33
         endCreateDate: "",
78
         endCreateDate: "",
34
         startVerifyDate: "",
79
         startVerifyDate: "",
35
         endVerifyDate: "",
80
         endVerifyDate: "",
36
-        status: "",
81
+        status: ""
37
       },
82
       },
38
       verifyPhone: "",
83
       verifyPhone: "",
39
       list: [],
84
       list: [],
70
       this.$router.push({ name: "goods.edit" });
115
       this.$router.push({ name: "goods.edit" });
71
     },
116
     },
72
     verifyTel() {
117
     verifyTel() {
73
-      this.$router.push({ name: "verify.list" , params: { tel: this.verifyPhone } });
118
+      this.$router.push({
119
+        name: "verify.list",
120
+        params: { tel: this.verifyPhone }
121
+      });
74
     },
122
     },
75
     toDetail(row) {
123
     toDetail(row) {
76
       this.$router.push({
124
       this.$router.push({
110
       this.$router.replace({ name: "goods.list", query: { page } });
158
       this.$router.replace({ name: "goods.list", query: { page } });
111
     },
159
     },
112
     formateDate(dt) {
160
     formateDate(dt) {
113
-      return !dt ? '' : dayjs(dt).format('YYYY-MM-DD HH:mm')
114
-    },
161
+      return !dt ? "" : dayjs(dt).format("YYYY-MM-DD HH:mm");
162
+    }
115
   },
163
   },
116
   created() {
164
   created() {
117
     this.pageNavi.current = this.$route.query.page || 1;
165
     this.pageNavi.current = this.$route.query.page || 1;
129
     border-radius: 50%;
177
     border-radius: 50%;
130
   }
178
   }
131
   img {
179
   img {
132
-      width: 100%;
133
-      height: 100%;
134
-    }
180
+    width: 100%;
181
+    height: 100%;
182
+  }
135
 }
183
 }
136
 .system-table-search {
184
 .system-table-search {
137
   width: calc(100% - 40px);
185
   width: calc(100% - 40px);
162
   position: relative;
210
   position: relative;
163
   overflow: hidden;
211
   overflow: hidden;
164
 }
212
 }
213
+.border-card {
214
+  .el-row {
215
+    margin: 60px auto;
216
+  }
217
+  .grid-content {
218
+    text-align: center;
219
+
220
+    .iconfont {
221
+      color: #77a5f0;
222
+      font-size: 24px;
223
+      margin-bottom: 8px;
224
+      display: inline-block;
225
+    }
226
+    p {
227
+      font-size: 13px;
228
+      margin: 0;
229
+      line-height: 1.4;
230
+      color: #666;
231
+    }
232
+  }
233
+}
165
 </style>
234
 </style>

+ 2
- 2
vue.config.js ファイルの表示

1
 module.exports = {
1
 module.exports = {
2
   publicPath: './',
2
   publicPath: './',
3
   devServer: {
3
   devServer: {
4
-    port: 9000,
4
+    port: 8080,
5
     proxy: {
5
     proxy: {
6
       '/api': {
6
       '/api': {
7
-        target: 'http://127.0.0.1:8080',
7
+        target: 'http://192.168.0.11:8080',
8
         changeOrigin: true,
8
         changeOrigin: true,
9
         // pathRewrite: {
9
         // pathRewrite: {
10
         //   '^/api': '/'
10
         //   '^/api': '/'