tremble 4 vuotta sitten
vanhempi
commit
c2704adc46

+ 49 - 0
admins/fd-mall-backstage/WEB-INF/page/shop/adminuser.html

@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>管理员列表</title>
+    #parse("sys/header.html")
+</head>
+<body>
+<div id="rrapp" v-cloak>
+    <div v-show="showList">
+        <Row :gutter="16">
+            <div class="search-group">
+                <i-col span="8">
+                    <div style="display: inline-block;">
+                        <i-input v-model="q.username" @on-enter="query" placeholder="请输入微信名称或用户名称"/>
+                    </div>
+                    <div style="display: inline-block;">
+                        <i-button @click="query">查询</i-button>
+                    </div>
+                </i-col>
+            </div>
+            <!-- <div class="buttons-group">
+                #if($shiro.hasPermission("sys:user:save"))
+                <i-button type="info" @click="add"><i class="fa fa-plus"></i>&nbsp;新增</i-button>
+                #end
+                #if($shiro.hasPermission("sys:user:update"))
+                <i-button type="warning" @click="update"><i class="fa fa-pencil-square-o"></i>&nbsp;修改</i-button>
+                #end
+                #if($shiro.hasPermission("sys:user:delete"))
+                <i-button type="error" @click="del"><i class="fa fa-trash-o"></i>&nbsp;删除</i-button>
+                #end
+            </div> -->
+        </Row>
+        <table id="jqGrid"></table>
+        <div id="jqGridPager"></div>
+    </div>
+
+    <div style="margin-top: 30px; text-align: center;">
+        <i-button type="primary" @click="submit">提交</i-button>
+        <i-button @click="close" style="margin-left: 8px">返回</i-button>
+    </div>
+
+</div>
+<!-- 选择部门 -->
+<div id="deptLayer" style="display: none;padding:10px;">
+    <ul id="deptTree" class="ztree"></ul>
+</div>
+<script src="${rc.contextPath}/js/shop/adminuser.js?_${date.systemTime}"></script>
+</body>
+</html>

+ 95 - 38
admins/fd-mall-backstage/WEB-INF/page/shop/brand.html

@@ -16,10 +16,11 @@
                     <div style="display: inline-block;">
                         <i-select v-model="q.type" >
                             <i-option value=" ">全部</i-option>
-                            <i-option value="0">其他</i-option>
-                            <i-option value="1">生活</i-option>
-                            <i-option value="2">文化</i-option>
-                            <i-option value="3">工业</i-option>
+                            <i-option value="0">服饰</i-option>
+                            <i-option value="1">家具</i-option>
+                            <i-option value="2">数码</i-option>
+                            <i-option value="3">娱乐</i-option>
+                            <i-option value="4">其他</i-option>
                         </i-select>
                     </div>
                     <div style="display: inline-block;">
@@ -43,11 +44,24 @@
         <table id="jqGrid"></table>
         <div id="jqGridPager"></div>
     </div>
-
+    <Spin fix v-if="loading">
+        <Icon type="load-c" size=18 class="demo-spin-icon-load"></Icon>
+        <div>上传中</div>
+    </Spin>
     <Card v-show="!showList">
         <p slot="title">{{title}}</p>
         <i-form ref="formValidate" :model="brand" :rules="ruleValidate" :label-width="110">
             <div style="width: 100%;">
+                <Form-item label="店铺类型" prop="type" style="width: 288px;">
+                    <div class="c-winput">
+                        <i-select v-model="brand.type">
+                            <i-option v-for="typeitem in typeList" :value="typeitem.id"
+                                    :key="typeitem.id">{{typeitem.name}}
+                            </i-option>
+                        </i-select>
+                    </div>
+
+                </Form-item>
                 <Form-item label="店铺名称" prop="name">
                     <div class="c-winput">
                         <i-input v-model="brand.name" placeholder="店铺名称"/>
@@ -72,12 +86,28 @@
                         </div>
                     </div>
                 </Form-item>
+
+                <Form-item label="店铺场景链接" prop="sceneUrl">
+                    <div class="c-winput">
+                        <i-button type="primary" @click="addSceneLink">编辑场景链接</i-button>
+                        <div>场景链接:{{brand.sceneUrl||'-'}}</div>
+                        <div>场景名称:{{brand.sceneName||'-'}}</div>
+                    </div>
+                    <!-- <div class="c-winput">
+                        <i-input v-model="brand.sceneUrl" placeholder="店铺场景链接"/>
+                    </div> -->
+                </Form-item>
+                
                    
-                <Form-item label="描述" prop="simpleDesc">
+                <Form-item label="店铺描述" prop="simpleDesc">
                     <div class="c-winput">
-                        <i-input type="textarea" v-model="brand.simpleDesc" placeholder="描述"/>
+                        <i-input type="textarea" v-model="brand.simpleDesc" placeholder="店铺描述"/>
                     </div>
                 </Form-item>
+
+                <Form-item label="店铺位置" prop="isShow">
+                    <v-select v-if="!showList" :areapath="brand.address" :longitude="brand.longitude" :latitude="brand.latitude"></v-select>
+                </Form-item>
                 <!-- <Row>
                     <i-col span="16">
                         <Form-item label="缩略图" prop="picUrl">
@@ -119,50 +149,73 @@
                     </div>
                 </Form-item>
     
-                <Form-item label="店铺类型" prop="type" style="width: 288px;">
-                    <div class="c-winput">
-                        <i-select v-model="brand.type">
-                            <i-option v-for="typeitem in typeList" :value="typeitem.id"
-                                    :key="typeitem.id">{{typeitem.name}}
-                            </i-option>
-                        </i-select>
-                    </div>
-
-                </Form-item>
-    
-                <Form-item label="店铺场景链接" prop="sceneUrl">
-                    <div class="c-winput">
-                        <i-button type="primary" @click='addSceneLink'>添加场景链接</i-button>
-                        <i-button type="primary" @click="addSceneLink">编辑场景链接</i-button>
-                        <!-- <div>{{brand.sceneUrl}}</div> -->
-                    </div>
-                    <!-- <div class="c-winput">
-                        <i-input v-model="brand.sceneUrl" placeholder="店铺场景链接"/>
-                    </div> -->
-                </Form-item>
-                
-                <Form-item label="分享图" prop="newPicUrl">
-                    <div class="c-winput">
-                        <i-input v-model="brand.newPicUrl" placeholder="分享图(宽高比:(5:4))" readonly/>
+           
+                <Form-item label="店铺图片" prop="picList">
+                    <div class="demo-upload-list" :key="i" v-for="(item,i) in brand.picList">
+                        <template v-if="item.status == 'finished'">
+                            <img :src="item.url">
+                            <div class="demo-upload-list-cover" >
+                                <i class="ivu-icon ivu-icon-eye" @click="eyeImage(item.name)"></i>
+                                <i class="ivu-icon ivu-icon-trash-a" @click="handleRemove(item)"></i>
+                            </div>
+                        </template>
+                        <template v-else>
+                            <Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
+                        </template>
                     </div>
                     <div class="c-btn">
                         <Upload action="../sys/oss/upload" :format="['jpg','jpeg','png']"
-                                max-size="2048"
-                                :on-success="handleSuccessNewPicUrl" :on-format-error="handleFormatError"
+                                :max-size="1024*10"
+                                :ref="'upload'"
+                                :default-file-list="defaultList"
+                                :on-success="handleSuccessBrandPicUrl" 
+                                :on-format-error="handleFormatError"
                                 :show-upload-list="false"
+                                :before-upload="handleBeforeUpload"
+                                multiple
                                 :on-exceeded-size="handleMaxSize">
-                            <i-button icon="ios-cloud-upload-outline">上传图片</i-button>
+                                <i-button icon="ios-cloud-upload-outline">上传图片</i-button>
                         </Upload>
                     </div>
+                        <p>1、支持png、jpg和gif图片格式;最多可上传15张。</p>
+                        <p>2、最大可上传10M的图片。</p>
+                    <div>
+                   </div>
+                </Form-item>
+
+                <Form-item label="视频" prop="newPicUrl">
+                    <div style="width: 50%;min-height: 400px;" v-show="brand.introduceVideo">
+                        <video controls style="width: 100%;" :src="brand.introduceVideo"></video>
+                    </div>
                     <div class="c-btn">
-                        <i-button icon="eye" @click="eyeImageNewPicUrl">预览图片</i-button>
+                        <Upload action="../sys/oss/upLoadVideo" :format="['mpeg','avi','wmv','mov','3gp','mp4']"
+                                :max-size="1024*1024"
+                                :before-upload="handleBefore"
+                                :on-success="handleSuccessVideoUrl" :on-format-error="handleFormatError"
+                                :show-upload-list="false"
+                                :on-exceeded-size="handleMaxSize">
+                            <i-button icon="ios-cloud-upload-outline">上传视频</i-button>
+                        </Upload>
                     </div>
-
+                   <div>
+                    <p>1、支持mpeg、avi、wmv、mov、3gp和mp4视频格式;</p>
+                    <p>2、最大可上传1G的视频。</p>
+                   </div>
                 </Form-item>
                 <!-- <Form-item label="新店铺排序" prop="newSortOrder">
                     <Input-number :min="0" :step="1" v-model="brand.newSortOrder" placeholder="新店铺排序"
                                   style="width: 188px;"/>
                 </Form-item> -->
+
+                <div style="font-size: 16px;font-weight: bold;margin-bottom: 10px;">相关负责人</div>
+
+                <Form-item label="店铺管理员:" prop="newSortOrder">
+                    <div class="c-winput">
+                        <div v-if="brand.nickname">{{brand.nickname}}</div>
+                        <i-button @click="openAdmin">选择店铺管理员</i-button>
+                    </div>
+                </Form-item>
+
                 <Form-item>
                     <i-button type="primary" @click="handleSubmit('formValidate')">提交</i-button>
                     <i-button type="warning" @click="reload" style="margin-left: 8px"/>
@@ -174,9 +227,13 @@
     </Card>
 
     <div id="loginLayer" style="display: none;height: 100%;">
-        <iframe id="loginfdkk" src="https://www.4dkankan.com/mall_login/login.html" style="height: 100%;width:100%" frameborder="0"></iframe>
+        <iframe id="loginfdkk" src="https://test.4dkankan.com/mall_login/login.html" style="height: 100%;width:100%" frameborder="0"></iframe>
     </div>
 </div>
+<script src="https://webapi.amap.com/maps?v=1.4.10&key=e661b00bdf2c44cccf71ef6070ef41b8"></script>
+<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.6&key=e661b00bdf2c44cccf71ef6070ef41b8&plugin=AMap.Geocoder"></script>
+<script type="text/javascript" src="https://webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>
+
 
 <script src="${rc.contextPath}/js/shop/brand.js?_${date.systemTime}"></script>
 </body>

+ 201 - 0
admins/fd-mall-backstage/WEB-INF/page/shop/broadcast.html

@@ -0,0 +1,201 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title></title>
+    #parse("sys/header.html")
+</head>
+<body>
+<div id="rrapp" v-cloak>
+    <div v-show="showList">
+        <Row :gutter="16">
+            <div class="search-group">
+                <i-col span="8" >
+                    <div style="display: inline-block;">
+                        <i-input v-model="q.name" @on-enter="query" placeholder="名称"/>
+                    </div>
+                    <div style="display: inline-block;">
+                        <i-button @click="query">查询</i-button>
+                    </div>
+                </i-col>
+            
+            </div>
+            <div class="buttons-group">
+                #if($shiro.hasPermission("brand:save"))
+                <i-button type="info" @click="add"><i class="fa fa-plus"></i>&nbsp;新增</i-button>
+                #end
+                #if($shiro.hasPermission("brand:delete"))
+                <i-button type="error" @click="del"><i class="fa fa-trash-o"></i>&nbsp;删除</i-button>
+                #end
+            </div>
+        </Row>
+        <table id="jqGrid"></table>
+        <div id="jqGridPager"></div>
+    </div>
+    <Spin fix v-if="loading">
+        <Icon type="load-c" size=18 class="demo-spin-icon-load"></Icon>
+        <div>上传中</div>
+    </Spin>
+    <Card v-show="!showList">
+        <p slot="title">{{title}}</p>
+        <i-form ref="formValidate" :model="broadcast" :rules="ruleValidate" :label-width="110">
+            <div style="width: 100%;">
+                <div style="font-size: 16px;font-weight: bold;margin-bottom: 10px;">基本信息</div>
+                <Form-item label="直播类型" prop="title">
+                    <div class="c-winput" >
+                        <Radio-group v-model="broadcast.type">
+                            <Radio label="1">
+                                <span>手机直播</span>
+                            </Radio>
+                        </Radio-group>
+                    </div>
+                </Form-item>
+                <Form-item label="直播间标题" prop="name">
+                    <div class="c-winput">
+                        <i-input v-model="broadcast.name" placeholder="直播间标题"/>
+                    </div>
+                </Form-item>
+                <Form-item label="直播开始时间" prop="startTime">
+                    <Date-picker @on-change="handleChangeStart" type="datetime" v-model="broadcast.startTime" placeholder="直播开始时间"></Date-picker>
+                </Form-item>
+                <Form-item label="直播结束时间" prop="endTime">
+                    <Date-picker @on-change="handleChangeEnd" type="datetime" v-model="broadcast.endTime" placeholder="直播结束时间"></Date-picker>
+                </Form-item>
+                <Form-item label="主播名称" prop="anchorName">
+                    <div class="c-winput">
+                        <i-input v-model="broadcast.anchorName" placeholder="主播名称"/>
+                    </div>
+                </Form-item>
+
+                <Form-item label="主播微信账号" prop="anchorWechat">
+                    <div class="c-winput">
+                        <i-input v-model="broadcast.anchorWechat" placeholder="填写微信账号"/>
+                    </div>
+                </Form-item>
+
+                <div style="font-size: 16px;font-weight: bold;margin-bottom: 10px;">直播间配置</div>
+
+
+                <Form-item label="分享卡片封面" prop="shareImg">
+                    <div class="demo-upload-list" v-if="broadcast.shareImg">
+                            <img :src="shareImg">
+                            <div class="demo-upload-list-cover" >
+                                <i class="ivu-icon ivu-icon-eye" @click="eyeImage(shareImg)"></i>
+                            </div>
+                    </div>
+                    <div class="c-btn">
+                        <Upload action="../liveRoom/uploadImage" :format="['jpg','jpeg','png']"
+                                :max-size="1024*10"
+                                :before-upload="beforeShareImgUpload"
+                                :on-success="handleSuccessShareImg" 
+                                :on-format-error="handleFormatError"
+                                :show-upload-list="false"
+                                :on-exceeded-size="handleMaxSize">
+                                <i-button icon="ios-cloud-upload-outline">上传图片</i-button>
+                        </Upload>
+                    </div>
+                        <p>分享卡片封面</p>
+                        <p>观众在微信对话框内分享的直播间将以分享卡片的形式呈现。</p>
+                        <p>建议尺寸:800像素 * 640像素,图片大小不得超过1M。</p>
+                    <div>
+                   </div>
+                </Form-item>
+
+                <Form-item label="直播卡片封面" prop="coverImg">
+                    <div class="demo-upload-list" v-if="broadcast.coverImg">
+                            <img :src="coverImg">
+                            <div class="demo-upload-list-cover" >
+                                <i class="ivu-icon ivu-icon-eye" @click="eyeImage(coverImg)"></i>
+                            </div>
+                    </div>
+                    <div class="c-btn">
+                        <Upload action="../liveRoom/uploadImage" :format="['jpg','jpeg','png']"
+                                :max-size="1024*10"
+                                :before-upload="beforecoverImgUpload"
+                                :on-success="handleSuccesscoverImg" 
+                                :on-format-error="handleFormatError"
+                                :show-upload-list="false"
+                                :on-exceeded-size="handleMaxSize">
+                                <i-button icon="ios-cloud-upload-outline">上传图片</i-button>
+                        </Upload>
+                    </div>
+                        <p>图片建议大小为 800像素 * 800像素。</p>
+                        <p>图片大小不超过 300KB。</p>
+                        <p>图片内容遵循平台规范后更容易被推荐。</p>
+                    <div>
+                   </div>
+                </Form-item>
+
+                <Form-item label="直播间背景墙" prop="feedsImg">
+                    <div class="demo-upload-list" v-if="broadcast.feedsImg">
+                            <img :src="feedsImg">
+                            <div class="demo-upload-list-cover" >
+                                <i class="ivu-icon ivu-icon-eye" @click="eyeImage(feedsImg)"></i>
+                            </div>
+                    </div>
+                    <div class="c-btn">
+                        <Upload action="../liveRoom/uploadImage" :format="['jpg','jpeg','png']"
+                                :max-size="1024*10"
+                                :before-upload="beforefeedsImgUpload"
+                                :on-success="handleSuccessfeedsImg" 
+                                :on-format-error="handleFormatError"
+                                :show-upload-list="false"
+                                :on-exceeded-size="handleMaxSize">
+                                <i-button icon="ios-cloud-upload-outline">上传图片</i-button>
+                        </Upload>
+                    </div>
+                        <p>直播间背景墙是每个直播间的默认背景。</p>
+                        <p>建议尺寸:1080像素 * 1920像素。</p>
+                        <p>图片大小不得超过2M。</p>
+                    <div>
+                   </div>
+                </Form-item>
+
+                <Form-item label="直播间功能" >
+                    <div class="c-winput">
+                        <Checkbox value="broadcast.closeComment" @on-change="(val)=>{broadcast.closeComment=!val*1}">评论</Checkbox>
+                        <Checkbox value="broadcast.closeGoods" @on-change="(val)=>{broadcast.closeGoods=!val*1}">商品货架</Checkbox>
+                        <Checkbox value="broadcast.closeShare" @on-change="(val)=>{broadcast.closeShare=!val*1}">分享</Checkbox>
+                        <Checkbox value="broadcast.closeLike" @on-change="(val)=>{broadcast.closeLike=!val*1}">点赞</Checkbox>
+                    </div>
+                </Form-item>
+
+                <Form-item label="回放">
+                    <div class="c-winput">
+                        <Radio-group v-model="broadcast.closeReplay">
+                            <Radio label="0">
+                                <span>是</span>
+                            </Radio>
+                            <Radio label="1">
+                                <span>否</span>
+                            </Radio>
+                        </Radio-group>
+                    </div>
+                </Form-item>
+
+                <Form-item label="客服">
+                    <div class="c-winput">
+                        <Radio-group v-model="broadcast.closeKf">
+                            <Radio label="0">
+                                <span>是</span>
+                            </Radio>
+                            <Radio label="1">
+                                <span>否</span>
+                            </Radio>
+                        </Radio-group>
+                    </div>
+                </Form-item>
+
+                <Form-item>
+                    <i-button type="primary" @click="handleSubmit('formValidate')">提交</i-button>
+                    <i-button type="warning" @click="reload" style="margin-left: 8px"/>
+                    返回</i-button>
+                    <i-button type="ghost" @click="handleReset('formValidate')" style="margin-left: 8px">重置</i-button>
+                </Form-item>
+            </div>
+        </i-form>
+    </Card>
+</div>
+
+<script src="${rc.contextPath}/js/shop/broadcast.js?_${date.systemTime}"></script>
+</body>
+</html>

+ 103 - 0
admins/fd-mall-backstage/WEB-INF/page/shop/carousel.html

@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title></title>
+    #parse("sys/header.html")
+</head>
+<body>
+<div id="rrapp" v-cloak>
+    <div v-show="showList">
+        <Row :gutter="16">
+            <div class="search-group">
+                <i-col span="8" >
+                    <div style="display: inline-block;">
+                        <i-input v-model="q.name" @on-enter="query" placeholder="名称"/>
+                    </div>
+                    <div style="display: inline-block;">
+                        <i-button @click="query">查询</i-button>
+                    </div>
+                </i-col>
+            </div>
+            <div class="buttons-group">
+                #if($shiro.hasPermission("brand:save"))
+                <i-button type="info" @click="add"><i class="fa fa-plus"></i>&nbsp;新增</i-button>
+                #end
+                #if($shiro.hasPermission("brand:update"))
+                <i-button type="warning" @click="update"><i class="fa fa-pencil-square-o"></i>&nbsp;修改</i-button>
+                #end
+                #if($shiro.hasPermission("brand:delete"))
+                <i-button type="error" @click="del"><i class="fa fa-trash-o"></i>&nbsp;删除</i-button>
+                #end
+            </div>
+        </Row>
+        <table id="jqGrid"></table>
+        <div id="jqGridPager"></div>
+    </div>
+    <Spin fix v-if="loading">
+        <Icon type="load-c" size=18 class="demo-spin-icon-load"></Icon>
+        <div>上传中</div>
+    </Spin>
+    <Card v-show="!showList">
+        <p slot="title">{{title}}</p>
+        <i-form ref="formValidate" :model="carousel" :rules="ruleValidate" :label-width="110">
+            <div style="width: 100%;">
+                <Form-item label="标题" prop="title">
+                    <div class="c-winput">
+                        <i-input v-model="carousel.title" placeholder="标题"/>
+                    </div>
+                </Form-item>
+                <Form-item label="轮播图片" prop="coverImage">
+                    <div class="demo-upload-list" v-if="carousel.coverImage">
+                            <img :src="carousel.coverImage">
+                            <div class="demo-upload-list-cover" >
+                                <i class="ivu-icon ivu-icon-eye" @click="eyeImage(carousel.coverImage)"></i>
+                            </div>
+                    </div>
+                    <div class="c-btn">
+                        <Upload action="../sys/oss/upload" :format="['jpg','jpeg','png']"
+                                :max-size="1024*10"
+                                :on-success="handleSuccessCarouselImage" 
+                                :on-format-error="handleFormatError"
+                                :show-upload-list="false"
+                                :on-exceeded-size="handleMaxSize">
+                                <i-button icon="ios-cloud-upload-outline">上传图片</i-button>
+                        </Upload>
+                    </div>
+                        <p>1、支持png、jpg和gif图片格式;最多可上传1张。</p>
+                        <p>2、最大可上传10M的图片。</p>
+                    <div>
+                   </div>
+                </Form-item>
+
+                <Form-item label="跳转链接">
+                    <div class="c-winput">
+                        <i-input v-model="carousel.redirectUrl" placeholder="跳转链接"/>
+                    </div>
+                </Form-item>
+
+                <Form-item label="排序">
+                    <div class="c-winput">
+                        <Input-number :min="0" :step="1" v-model="carousel.order" placeholder="排序" style="width: 188px;"/>
+                    </div>
+                </Form-item>
+
+                <Form-item label="备注">
+                    <div class="c-winput">
+                        <i-input type="textarea" v-model="carousel.remark" placeholder="备注"/>
+                    </div>
+                </Form-item>
+
+                <Form-item>
+                    <i-button type="primary" @click="handleSubmit('formValidate')">提交</i-button>
+                    <i-button type="warning" @click="reload" style="margin-left: 8px"/>
+                    返回</i-button>
+                    <i-button type="ghost" @click="handleReset('formValidate')" style="margin-left: 8px">重置</i-button>
+                </Form-item>
+            </div>
+        </i-form>
+    </Card>
+</div>
+
+<script src="${rc.contextPath}/js/shop/carousel.js?_${date.systemTime}"></script>
+</body>
+</html>

+ 59 - 40
admins/fd-mall-backstage/WEB-INF/page/shop/coupon.html

@@ -9,18 +9,35 @@
     <div v-show="showList">
         <Row :gutter="16">
             <div class="search-group">
-                <i-col span="4">
-                    <i-input v-model="q.name" @on-enter="query" placeholder="优惠券名称"/>
+                <i-col span="12" >
+                    <div style="display: inline-block;">
+                        <i-input v-model="q.name" @on-enter="query" placeholder="优惠券名称"/>
+                    </div>
+                    <div style="display: inline-block;">
+                        <i-input v-model="q.brandName" @on-enter="query" placeholder="店铺名称"/>
+                    </div>
+                    <div style="display: inline-block;width:100px">
+                        <i-select v-model="q.couponStatus" >
+                            <i-option value=" ">全部</i-option>
+                            <i-option value="1">未生效</i-option>
+                            <i-option value="2">生效中</i-option>
+                            <i-option value="3">已失效</i-option>
+                            <i-option value="4">停止发放</i-option>
+                        </i-select>
+                    </div>
+                    <div style="display: inline-block;">
+                        <i-button @click="query">查询</i-button>
+                    </div>
                 </i-col>
-                <i-button @click="query">查询</i-button>
+                
             </div>
             <div class="buttons-group">
                 #if($shiro.hasPermission("coupon:save"))
                 <i-button type="info" @click="add"><i class="fa fa-plus"></i>&nbsp;新增</i-button>
                 #end
-                #if($shiro.hasPermission("coupon:update"))
+                <!-- #if($shiro.hasPermission("coupon:update"))
                 <i-button type="warning" @click="update"><i class="fa fa-pencil-square-o"></i>&nbsp;修改</i-button>
-                #end
+                #end -->
                 #if($shiro.hasPermission("coupon:delete"))
                 <i-button type="error" @click="del"><i class="fa fa-trash-o"></i>&nbsp;删除</i-button>
                 #end
@@ -38,59 +55,61 @@
 
     <Card v-show="showCard">
         <p slot="title">{{title}}</p>
-        <i-form ref="formValidate" :model="coupon" :rules="ruleValidate" :label-width="100">
+        <i-form ref="formValidate" :model="coupon" :rules="ruleValidate" :label-width="150">
+            <Form-item label="店铺名称" prop="brandId" style="width: 468px;">
+                <i-select  v-if="title=='新增'" v-model="coupon.brandId" filterable>
+                    <i-option v-for="brand in brands" :value="brand.id" :key="brand.id">{{brand.name}}
+                    </i-option>
+                </i-select>
+                <span v-else v-html="coupon.brandName"></span>
+            </Form-item>
             <Form-item label="优惠券名称" prop="name">
                 <i-input v-model="coupon.name" placeholder="优惠券名称"/>
             </Form-item>
-            <Form-item label="金额" prop="typeMoney">
-                <Input-number :min="0" v-model="coupon.typeMoney" placeholder="金额" style="width: 188px;"/>
+            <Form-item label="面值金额" prop="typeMoney">
+                <Input-number :min="0" :max="9999" v-model="coupon.typeMoney" placeholder="面值金额" style="width: 200px;"/>
             </Form-item>
-            <Form-item label="发放方式" prop="sendType">
+            <Form-item label="最小订单金额" prop="minGoodsAmount">
+                <Input-number :min="0" :max="99999999" v-model="coupon.minGoodsAmount" placeholder="最小订单金额" style="width: 200px;"/>
+            </Form-item>
+            <!-- <Form-item label="发放方式" prop="sendType">
                 <Radio-group v-model="coupon.sendType">
                     <Radio label="0">
                         <span>按订单发放</span>
                     </Radio>
-                    <Radio label="1">
-                        <span>按用户发放</span>
-                    </Radio>
-                    <Radio label="2">
-                        <span>商品转发送券</span>
-                    </Radio>
-                    <!--<Radio label="3">-->
-                    <!--<span>按商品发放</span>-->
-                    <!--</Radio>-->
-                    <Radio label="4">
-                        <span>新用户注册</span>
-                    </Radio>
-                    <!--<Radio label="5">-->
-                    <!--<span>线下发放</span>-->
-                    <!--</Radio>-->
-                    <Radio label="7">
-                        <span>包邮优惠</span>
-                    </Radio>
                 </Radio-group>
+            </Form-item> -->
+
+            <Form-item label="发放数量" prop="number">
+                <Input-number :min="0" v-model="coupon.number" placeholder="发放数量" style="width: 200px;"/>
+            </Form-item>
+           
+            <Form-item label="使用开始时间" prop="useStartDate">
+                <Date-picker type="datetime" v-model="coupon.useStartDate" placeholder="使用开始时间"></Date-picker>
             </Form-item>
-            <Form-item label="最小金额" prop="minAmount">
-                <Input-number :min="0" v-model="coupon.minAmount" placeholder="最小金额" style="width: 188px;"/>
+            <Form-item label="使用结束时间" prop="useEndDate">
+                <Date-picker type="datetime" v-model="coupon.useEndDate" placeholder="使用结束时间"></Date-picker>
+            </Form-item>
+
+            <Form-item label="使用说明" prop="useDesc">
+                <div class="c-winput">
+                    <i-input type="textarea" v-model="coupon.useDesc" placeholder="描述"/>
+                </div>
+            </Form-item>
+
+            <!-- <Form-item label="最小金额" prop="minAmount">
+                <Input-number :min="0" v-model="coupon.minAmount" placeholder="最小金额" style="width: 200px;"/>
             </Form-item>
             <Form-item label="最大金额" prop="maxAmount">
-                <Input-number :min="0" v-model="coupon.maxAmount" placeholder="最大金额" style="width: 188px;"/>
+                <Input-number :min="0" v-model="coupon.maxAmount" placeholder="最大金额" style="width: 200px;"/>
             </Form-item>
             <Form-item label="发放开始时间" prop="sendStartDate">
                 <Date-picker v-model="coupon.sendStartDate" placeholder="发放开始时间"></Date-picker>
             </Form-item>
             <Form-item label="发放结束时间" prop="sendEndDate">
                 <Date-picker v-model="coupon.sendEndDate" placeholder="发放结束时间"></Date-picker>
-            </Form-item>
-            <Form-item label="使用开始时间" prop="useStartDate">
-                <Date-picker v-model="coupon.useStartDate" placeholder="使用开始时间"></Date-picker>
-            </Form-item>
-            <Form-item label="使用结束时间" prop="useEndDate">
-                <Date-picker v-model="coupon.useEndDate" placeholder="使用结束时间"></Date-picker>
-            </Form-item>
-            <Form-item label="最小商品金额" prop="minGoodsAmount">
-                <Input-number :min="0" v-model="coupon.minGoodsAmount" placeholder="最小商品金额" style="width: 188px;"/>
-            </Form-item>
+            </Form-item> -->
+           
             <Form-item>
                 <i-button type="primary" @click="handleSubmit('formValidate')">提交</i-button>
                 <i-button type="warning" @click="reload" style="margin-left: 8px"/>

+ 77 - 0
admins/fd-mall-backstage/WEB-INF/page/shop/coupondetail.html

@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title></title>
+    #parse("sys/header.html")
+</head>
+<body>
+<div id="rrapp" v-cloak>
+    <div v-show="showList">
+        <Row :gutter="16">
+            <div class="search-group">
+                <i-col span="12" >
+                    <div style="display: inline-block;">
+                        <i-input v-model="q.orderId" @on-enter="query" placeholder="订单号"/>
+                    </div>
+                    <div style="display: inline-block;">
+                        <i-input v-model="q.userName" @on-enter="query" placeholder="会员名称"/>
+                    </div>
+                    <div style="display: inline-block;">
+                        <i-select v-model="q.useStatus" >
+                            <i-option value=" ">全部</i-option>
+                            <i-option value="1">已领取</i-option>
+                            <i-option value="2">已使用</i-option>
+                            <i-option value="3">已过期</i-option>
+                            <i-option value="4">已作废</i-option>
+                        </i-select>
+                    </div>
+                    <div style="display: inline-block;">
+                        <i-button @click="query">查询</i-button>
+                    </div>
+                </i-col>
+            </div>
+            <!--#if($shiro.hasPermission("usercoupon:save"))-->
+            <!--<i-button type="info" @click="add"><i class="fa fa-plus"></i>&nbsp;新增</i-button>-->
+            <!--#end-->
+            <!--#if($shiro.hasPermission("usercoupon:update"))-->
+            <!--<i-button type="warning" @click="update"><i class="fa fa-pencil-square-o"></i>&nbsp;修改</i-button>-->
+            <!--#end-->
+            <div class="buttons-group">
+            </div>
+        </Row>
+        店铺名称:{{brandName}}<span style="display: inline-block;margin: 0 10px;"></span>优惠券名称:{{name}}
+        <table id="jqGrid"></table>
+        <div id="jqGridPager"></div>
+    </div>
+
+    <Card v-show="!showList">
+        <p slot="title">{{title}}</p>
+        <i-form :model="userCoupon" :label-width="80">
+            <Form-item label="优惠券Id" prop="couponId">
+                <i-input v-model="userCoupon.couponId" placeholder="优惠券Id"/>
+            </Form-item>
+            <Form-item label="优惠券数量" prop="couponNumber">
+                <i-input v-model="userCoupon.couponNumber" placeholder="优惠券数量"/>
+            </Form-item>
+            <Form-item label="会员Id" prop="userId">
+                <i-input v-model="userCoupon.userId" placeholder="会员Id"/>
+            </Form-item>
+            <Form-item label="使用时间" prop="usedTime">
+                <Date-picker v-model="userCoupon.usedTime" placeholder="使用时间"/>
+            </Form-item>
+            <Form-item label="订单Id" prop="orderId">
+                <i-input v-model="userCoupon.orderId" placeholder="订单Id"/>
+            </Form-item>
+            <Form-item>
+                <i-button type="primary" @click="handleSubmit('formValidate')">提交</i-button>
+                <i-button type="warning" @click="reload" style="margin-left: 8px"/>
+                返回</i-button>
+                <i-button type="ghost" @click="handleReset('formValidate')" style="margin-left: 8px">重置</i-button>
+            </Form-item>
+        </i-form>
+    </Card>
+</div>
+
+<script src="${rc.contextPath}/js/shop/coupondetail.js?_${date.systemTime}"></script>
+</body>
+</html>

+ 12 - 17
admins/fd-mall-backstage/WEB-INF/page/shop/goods.html

@@ -66,33 +66,28 @@
                                 <i-input v-model="goods.name" placeholder="名称"/>
                             </div>
                         </Form-item>
+
+                        <Form-item label="商品描述" prop="goodsSimpleDesc">
+                            <div class="c-winput">
+                                <i-input v-model="goods.goodsSimpleDesc" placeholder="商品描述"/>
+                            </div>
+                        </Form-item>
                         
                         <Form-item label="店铺" prop="brandId" style="width: 268px;">
-                            <i-select v-model="goods.brandId" filterable>
+                            <i-select  v-if="title=='新增'" v-model="goods.brandId" filterable>
                                 <i-option v-for="brand in brands" :value="brand.id" :key="brand.id">{{brand.name}}
                                 </i-option>
                             </i-select>
+                            <span v-else v-html="goods.brandName"></span>
                         </Form-item>
-                        
-                        <!-- <Form-item label="商品库存" prop="goodsNumber">
-                            <div class="c-winput">
-                                <Input-number :min="1" :step="1" v-model="goods.goodsNumber" placeholder="商品库存" style="width: 188px;"/>
-                            </div>
-                        </Form-item>
-                  
-                        <Form-item label="零售价格" prop="retailPrice">
+
+                        <Form-item label="购买链接"  prop="realShopUrl">
                             <div class="c-winput">
-                                <Input-number :min="1" :step="1" v-model="goods.retailPrice" placeholder="零售价格" style="width: 188px;"/>
+                                <i-input v-model="goods.realShopUrl" placeholder="购买链接"/>
                             </div>
+                            <span style="color:#aaa;margin-left: 10px;">仅支持京东链接</span>
                         </Form-item>
                         
-                        <Form-item label="市场价" prop="marketPrice">
-                            <div class="c-winput">
-                                <Input-number :min="1" :step="1" v-model="goods.marketPrice" placeholder="市场价" style="width: 188px;"/>
-                            </div>
-
-                        </Form-item> -->
-
                         <Form-item label="商品规格">
                             <div class="items-ge">
                                 <div class="item-ge" v-for="(item,i) in guigeArr" :key="i">

+ 3 - 3
admins/fd-mall-backstage/WEB-INF/page/sys/main.html

@@ -33,7 +33,7 @@
         }
 
         .box-center img{
-            width: 250px;
+            width: 190px;
             position: absolute;
             top: -160px;
             left: -100px;
@@ -67,8 +67,8 @@
 <div class=" animated fadeInRight">
     <img  src="http://4d-tjw.oss-cn-shenzhen.aliyuncs.com/images/login_bg.jpg" alt="">
     <div class="box-center">
-        <img src="https://shop.4dkankan.com/platform-framework/statics/img/logo.png" alt="">
-        <p>四维商圈新体验:</p>
+        <img src="https://testshop.4dkankan.com/platform-framework/statics/img/logo.png" alt="">
+        <p>看店4DKanKan新体验:</p>
         <p>宅家中,云逛街,轻松买</p>
     </div>
 </div>

+ 2 - 2
admins/fd-mall-backstage/config/config.js

@@ -1,5 +1,5 @@
 // 给webpack读取的配置文件
 module.exports = {
-    title: '四维商圈管理平台',
-    navTitle: '四维商圈管理平台',
+    title: '看店4DKanKan管理平台',
+    navTitle: '看店4DKanKan管理平台',
 }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
admins/fd-mall-backstage/index.html


+ 2 - 2
admins/fd-mall-backstage/js/common.js

@@ -458,10 +458,10 @@ Ajax = function () {
                   opt.successCallback(data);
               }
           },
-          error: function () {
+          error: function (data) {
               //关闭遮罩
               dialogLoading(false);
-              layer.alert("此页面发生未知异常,请联系管理员", {icon: 5});
+              layer.alert(data.msg, {icon: 5});
           }
       });
   }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
admins/fd-mall-backstage/js/shop/brand.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
admins/fd-mall-backstage/js/shop/coupon.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
admins/fd-mall-backstage/js/shop/goods.js


+ 3 - 3
admins/fd-mall-backstage/login.html

@@ -3,7 +3,7 @@
 <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <title>四维商圈管理平台</title>
+    <title>看店4DKanKan管理平台</title>
     <!-- Tell the browser to be responsive to screen width -->
     <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
     <link rel="stylesheet" href="statics/css/bootstrap.min.css">
@@ -44,13 +44,13 @@
     <div class="col-md-9">
         <div class="login-info">
             <img src="./statics/img/logo.png" alt="">
-            <p>四维商圈新体验:</p>
+            <p>看店4DKanKan新体验:</p>
             <p>宅家中,云逛街,轻松买</p>
         </div>        
     </div>
     <div class="col-md-3">
         <Card class="m-t text-center" style="background: rgba(109, 109, 109, 0.23);border: 0px solid #dddee1;">
-            <p style="padding: 0 20px 20px 20px;">登录到四维商圈管理平台</p>
+            <p style="padding: 0 20px 20px 20px;">登录到看店4DKanKan管理平台</p>
             <div class="form-group has-feedback">
                 <i-input v-model="username" @on-enter="login" placeholder="账号" style="width: 240px;" autofocus/>
             </div>

+ 67 - 0
admins/fd-mall-backstage/statics/css/main.css

@@ -370,3 +370,70 @@ tbody > tr > th {
     width: 90%;
 }
 
+.norecords {
+    border-width: 2px !important;
+	display:none;
+    font-weight: bold;
+    left: 45%;
+    margin: 5px;
+    padding: 6px;
+    position: absolute;
+    text-align: center;
+    top: 45%;
+    width: auto;
+    z-index: 102;
+}
+
+.demo-upload-list{
+    display: inline-block;
+    width: 160px;
+    height: auto;
+    text-align: center;
+    line-height: 160px;
+    border: 1px solid transparent;
+    border-radius: 4px;
+    overflow: hidden;
+    background: #fff;
+    position: relative;
+    box-shadow: 0 1px 1px rgba(0,0,0,.2);
+    margin-right: 4px;
+}
+.demo-upload-list img{
+    width: 100%;
+    height: 100%;
+}
+.demo-upload-list-cover{
+    position: absolute;
+    opacity: 0;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    background: rgba(0,0,0,.6);
+}
+.demo-upload-list:hover .demo-upload-list-cover{
+    opacity: 1;
+}
+.demo-upload-list-cover i{
+    color: #fff;
+    font-size: 20px;
+    cursor: pointer;
+    margin: 0 2px;
+}
+
+.demo-spin-icon-load{
+    animation: ani-demo-spin 1s linear infinite;
+}
+@keyframes ani-demo-spin {
+    from { transform: rotate(0deg);}
+    50%  { transform: rotate(180deg);}
+    to   { transform: rotate(360deg);}
+}
+.demo-spin-col{
+    height: 100px;
+    position: relative;
+    border: 1px solid #eee;
+}
+.ivu-spin-fix{
+    z-index:500!important;
+}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
admins/zl-mall-backstage/js/shop/brand.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
admins/zl-mall-backstage/js/shop/coupon.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
admins/zl-mall-backstage/js/shop/goods.js


+ 10 - 7
js/common.js

@@ -15,6 +15,8 @@ $.ajaxSetup({
     cache: false
 });
 
+window.commonVue = new Vue()
+
 //重写alert
 window.alert = function (msg, callback) {
     // parent.layer.alert 弹出在iframe外的页面。
@@ -305,12 +307,9 @@ function dialogLoading(flag) {
  * @constructor
  */
 function getQueryString(name) {
-    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
+    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
     var r = window.location.search.substr(1).match(reg);
-    if (r != null) {
-        return unescape(r[2]);
-    }
-    return null;
+    if (r != null) return decodeURI(r[2]); return null;
 }
 
 /**
@@ -432,6 +431,10 @@ Ajax = function () {
                 //关闭遮罩
                 dialogLoading(false);
 
+                if(data.code === 500){
+                    layer.alert(data.msg, {icon: 5});
+                    return;
+                }
                 if (typeof data == 'string' && data.indexOf("exception") > 0 || typeof data.code != 'undefined' && data.code != '0') {
                     var result = {code: null};
                     if (typeof data == 'string') {
@@ -458,10 +461,10 @@ Ajax = function () {
                     opt.successCallback(data);
                 }
             },
-            error: function () {
+            error: function (data) {
                 //关闭遮罩
                 dialogLoading(false);
-                layer.alert("此页面发生未知异常,请联系管理员", {icon: 5});
+                layer.alert(data.msg, {icon: 5});
             }
         });
     }

+ 293 - 0
js/shop/adminuser.js

@@ -0,0 +1,293 @@
+$(function () {
+    $("#jqGrid").Grid({
+        url: '../user/list',
+        rownumWidth:60,
+        colModel: [
+            {label: 'id', name: 'id', index: 'id', key: true, hidden: true},
+            {label: '会员名称', name: 'nickname', index: "nickname", key: true, hidden: true},
+            {label: '微信名称', name: 'username', index: 'username', width: 75},
+            {label: '手机号', name: 'mobile', index: 'mobile', width: 100},
+            {label: '已绑定的店铺', name: 'brandName',index: 'brand_name', width: 100,sortable:false}]
+    });
+});
+
+var setting = {
+    data: {
+        simpleData: {
+            enable: true,
+            idKey: "deptId",
+            pIdKey: "parentId",
+            rootPId: -1
+        },
+        key: {
+            url: "nourl"
+        }
+    }
+};
+var ztree;
+
+const validatePhoneCheck = function (rule, value, callback){
+    if (value === ''||!value) {
+        callback(new Error('手机号不能为空'));
+    } else if(!(/^1[3456789]\d{9}$/.test(value))){
+        callback(new Error('手机号不正确'));
+    } else {
+        callback();
+    }
+};
+
+var vm = new Vue({
+    el: '#rrapp',
+    data: {
+        modal1:false,
+        q: {
+            username: null
+        },
+        showList: true,
+        title: null,
+        roleList: {},
+        user: {
+            status: 1,
+            deptName: '',
+            roleIdList: [],
+            brandIdList: [],
+            brandList: []
+        },
+        ruleValidate: {
+            username: [
+                {required: true, message: '姓名不能为空', trigger: 'blur'}
+            ],
+            email: [
+                {required: true, message: '邮箱不能为空', trigger: 'blur'},
+                {type: 'email', message: '邮箱格式不正确', trigger: 'blur'}
+            ],
+            mobile: [
+                {required: true, validator: validatePhoneCheck, trigger: 'blur'}
+            ]
+        },
+        brandsList:[],
+        brandPage:1,
+        brandPerPage:10,
+        brandTotal:0,
+        brandSeleced:[],
+        social:[],
+        cacheData:{},
+        cacheDataFirst:{}
+    },
+    watch:{
+        brandPage:function name(newVal) {
+            this.getBrandList()
+        }
+    },
+    methods: {
+        submit(){
+            var data = getSelectedRowData("#jqGrid");
+            console.log(data)
+             if (data.id == null) {
+                 return;
+             }
+            window.parent.postMessage({
+                userId:data.id,
+                nickname:data.nickname,
+              }, '*');
+        },
+        close(){
+            window.parent.postMessage('close', '*');
+        },
+        clickCheck:function(item,idx){
+            item['checked'] = !item['checked']
+            this.$set(this.brandsList,idx,item)
+        },
+        ok: function() {
+            let temp = []
+            let tempid = []
+            var that = this
+            Object.keys(vm.cacheData).forEach(function(item){
+                that.cacheData[item].page.list.forEach(function(sub){
+                    if (sub['checked']) {
+                        temp.push(sub)
+                        tempid.push(sub.id)
+                    }
+                })
+            })
+            vm.user.brandList = temp
+            vm.user.brandIdList = tempid
+        },
+        cancel:function () {
+            this.cacheData={}
+            this.modal1 = false
+        },
+        query: function () {
+            vm.reload();
+        },
+        add: function () {
+            vm.showList = false;
+            vm.title = "新增(默认密码:888888)";
+            vm.roleList = {};
+            vm.user = {status: 1, roleIdList: [], brandIdList:[], deptId: '', deptName: ''};
+
+            //获取角色信息
+            this.getRoleList();
+            vm.getDept();
+        },
+        getDept: function () {
+            //加载部门树
+            Ajax.request({
+                url: '../sys/dept/list',
+                async: true,
+                successCallback: function (r) {
+                    ztree = $.fn.zTree.init($("#deptTree"), setting, r.list);
+                    var node = ztree.getNodeByParam("deptId", vm.user.deptId);
+                    if (node != null) {
+                        ztree.selectNode(node);
+
+                        vm.user.deptName = node.name;
+                    }
+                }
+            });
+        },
+        pageChange:function(page){
+            this.brandPage = page
+        },
+        getBrandList: function () {
+            this.modal1 = true
+            if (this.cacheData[this.brandPage]) {
+                let temp = this.cacheData[this.brandPage]
+                this.brandsList = temp.page.list
+                this.brandPage = temp.page.currPage
+                this.brandTotal = temp.page.totalCount
+                return
+            }
+            let that = this
+
+            Ajax.request({
+                url: '../brand/list?_search=false&limit='+that.brandPerPage+'&page='+that.brandPage+'&sidx=&order=asc',
+                async: true,
+                successCallback: function (res) {
+                    res.page.list.forEach(function (item,index){
+                            item['checked'] = false
+                            if (that.user.brandList) {
+                                that.user.brandList.forEach(function(sub){
+                                    // item['checked'] = false
+                                    if (item.id===sub.brandId||item.id===sub.id) {
+                                    item['checked'] = true
+                                        return
+                                    }
+                                })
+                            }
+                        })
+
+                        that.cacheData[res.page.currPage] = res
+                        that.brandsList = res.page.list
+                        that.brandPage = res.page.currPage
+                        that.brandTotal = res.page.totalCount
+                }
+            });
+        },
+        update: function () {
+            var userId = getSelectedRow("#jqGrid");
+            if (userId == null) {
+                return;
+            }
+
+            vm.showList = false;
+            vm.title = "修改";
+
+            Ajax.request({
+                url: "../sys/user/info/" + userId,
+                async: true,
+                successCallback: function (r) {
+                    vm.user = r.user;
+                    //获取角色信息
+                    vm.getRoleList();
+                    vm.getDept();
+                }
+            });
+
+        },
+        del: function () {
+            var userIds = getSelectedRows("#jqGrid");
+            if (userIds == null) {
+                return;
+            }
+
+            confirm('确定要删除选中的记录?', function () {
+                Ajax.request({
+                    url: "../sys/user/delete",
+                    params: JSON.stringify(userIds),
+                    contentType: "application/json",
+                    type: 'POST',
+                    successCallback: function () {
+                        alert('操作成功', function (index) {
+                            vm.reload();
+                        });
+                    }
+                });
+            });
+        },
+        saveOrUpdate: function (event) {
+            var url = vm.user.userId == null ? "../sys/user/save" : "../sys/user/update";
+            Ajax.request({
+                url: url,
+                params: JSON.stringify(vm.user),
+                contentType: "application/json",
+                type: 'POST',
+                successCallback: function () {
+                    alert('操作成功', function (index) {
+                        vm.reload();
+                    });
+                }
+            });
+        },
+        getRoleList: function () {
+            Ajax.request({
+                url: '../sys/role/select',
+                async: true,
+                successCallback: function (r) {
+                    vm.roleList = r.list;
+                }
+            });
+        },
+        reload: function (event) {
+            vm.showList = true;
+            var page = $("#jqGrid").jqGrid('getGridParam', 'page');
+            $("#jqGrid").jqGrid('setGridParam', {
+                postData: {'username': vm.q.username},
+                page: page
+            }).trigger("reloadGrid");
+            vm.handleReset('formValidate');
+        },
+        deptTree: function () {
+            openWindow({
+                title: "选择部门",
+                area: ['300px', '450px'],
+                content: jQuery("#deptLayer"),
+                btn: ['确定', '取消'],
+                btn1: function (index) {
+                    var node = ztree.getSelectedNodes();
+                    //选择上级部门
+                    vm.user.deptId = node[0].deptId;
+                    vm.user.deptName = node[0].name;
+
+                    layer.close(index);
+                }
+            });
+        },
+        handleSubmit: function (name) {
+            handleSubmitValidate(this, name, function () {
+                vm.saveOrUpdate()
+            });
+        },
+        handleReset: function (name) {
+            handleResetForm(this, name);
+            this.cacheData = {}
+            this.user= {
+                status: 1,
+                deptName: '',
+                roleIdList: [],
+                brandIdList: [],
+                brandList: []
+            }
+        }
+    }
+});

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 5088 - 41
js/shop/brand.js


+ 296 - 0
js/shop/broadcast.js

@@ -0,0 +1,296 @@
+let cacheData = {
+}
+$(function () {
+    var types = {
+     0:'服饰',
+     1:'家具',
+     2:'数码',
+     3:'娱乐',
+     4:'其他',
+    }
+     
+     $("#jqGrid").Grid({
+         url: '../liveRoom/getRoomList',
+         rownumWidth:60,
+         colModel: [{
+             label: 'id', name: 'id', index: 'liveId', key: true, hidden: true
+         }, 
+         {
+            label: 'liveId', name: 'liveId', index: 'liveId', hidden: true
+        }, 
+         {
+             label: '最近开播', name: 'startTime', index: 'startTime', width: 80,formatter: function (value, col, row) {
+                cacheData[col.rowId] = row
+                return transDate(parseInt(value)*1000);
+            }
+         },
+         {
+            label: '直播名称', name: 'name', index: 'name', width: 80
+        },
+         {
+            label: '直播分享图',align:'center', name: 'shareImg', index: 'shareImg', width: 120, formatter: function (value) {
+                return transImg(value,100,'auto');
+            }
+        },
+        {
+            label: '房间号', name: 'roomId', index: 'roomId', width: 80
+        },
+        {
+            label: '主播', name: 'anchorName', index: 'anchorName', width: 80
+        },
+        {
+            label: '直播状态', name: 'liveStatus', index: 'liveStatus', width: 80
+        }
+     ]
+     });
+  });
+  
+  
+  const validateSceneUrlCheck = function (rule, value, callback){
+     var link1 ='https://test.4dkankan.com/eShopMobile.html?m='
+     var link2 ='https://www.4dkankan.com/eShopMobile.html?m='
+  
+     if (value === ''||!value) {
+         callback(new Error('场景地址不能为空'));
+     } else if(!~value.indexOf(link1)&&!~value.indexOf(link2)){
+         callback(new Error('场景地址需为'+link2+'或'+link1));
+     } else {
+         callback();
+     }
+  };
+
+  const validateNotNullIdCheck =function (rule, value, callback)  {
+    if (value === '' || !value) {
+        callback(new Error(rule.name+'不能为空'));
+    }else {
+        callback();
+    }
+};
+  
+  var vm = new Vue({
+     el: '#rrapp',
+     data: {
+        loading:false,
+         showList: true,
+         title: null,
+         broadcast: {name: '',coverImg:'',startTime:'',endTime:'',anchorName:'',anchorWechat:'', shareImg: '',feedsImg: '',screenType:0,isFeedsPublic: 0,type: 1,closeLike:0, closeGoods: 0,closeKf:0, closeComment: 0,closeReplay: 0,closeShare: 0},
+         func:['closeComment','closeGoods'],
+         ruleValidate: {
+            name: [
+                {required: true, message: '直播间标题不能为空', trigger: 'blur'}
+            ],
+            startTime: [
+                {required: true, name: '直播开始时间',validator: validateNotNullIdCheck,  trigger: 'change'}
+            ],
+            endTime: [
+                {required: true, name: '直播结束时间',validator: validateNotNullIdCheck,  trigger: 'change'}
+            ],
+            anchorName: [
+                {required: true, message: '主播名称不能为空', trigger: 'blur'}
+            ],
+            anchorWechat: [
+                {required: true, message: '主播微信账号不能为空', trigger: 'blur'}
+            ],
+            shareImg: [
+                {required: true, message: '分享卡片封面不能为空', trigger: 'blur'}
+            ],
+            coverImg: [
+                {required: true, message: '直播卡片封面不能为空', trigger: 'blur'}
+            ],
+            feedsImg: [
+                {required: true, message: '直播间背景墙不能为空', trigger: 'blur'}
+            ]
+         },
+         q: {
+             name: ''
+         },
+         coverImg:'',
+         shareImg:'',
+         feedsImg:'',
+         startTime:'',
+         endTime:''
+     },
+     methods: {
+        handleRemove (file) {
+            
+        },
+         query: function () {
+             vm.reload();
+         },
+         add: function () {
+             vm.showList = false;
+             vm.title = "新增";
+             vm.broadcast =   {name: '',coverImg:'',startTime:'',endTime:'',anchorName:'',anchorWechat:'', shareImg: '',feedsImg: '',screenType:0,isFeedsPublic: 0,type: 1,closeLike:0, closeGoods: 0,closeKf:0, closeComment: 0,closeReplay: 0,closeShare: 0}
+         },
+         update: function (event) {
+             var data = getSelectedRowData("#jqGrid");
+             if (data.id == null) {
+                 return;
+             }
+             vm.showList = false;
+             vm.title = "修改";
+  
+             vm.getInfo(data.slideId)
+         },
+         saveOrUpdate: function (event) {
+             var url = vm.broadcast.slideId == null ? "../liveRoom/add" : "../liveRoom/update";
+             Ajax.request({
+                 type: "POST",
+                 url: url,
+                 contentType: "application/json",
+                 params: JSON.stringify(Object.assign(vm.broadcast,{
+                    startTime:vm.startTime,
+                    endTime:vm.endTime
+                 })),
+                 successCallback: function () {
+                     alert('操作成功', function (index) {
+                         vm.reload();
+                     });
+                 }
+             });
+         },
+         handleChangeStart(val){
+             let date = new Date(val)
+             this.startTime = parseInt(date.getTime()/1000)
+         },
+         handleChangeEnd(val){
+            let date = new Date(val)
+            this.endTime = parseInt(date.getTime()/1000)
+         },
+         funChange(val){
+            console.log(this.func)
+            console.log(val)
+            
+         },
+         del: function (event) {
+             
+            let rowId = getSelectedRow("#jqGrid");
+            if (rowId == null) {
+                return;
+            }
+            var data = cacheData[rowId]
+            
+             confirm('确定要删除选中的记录?', function () {
+  
+                 Ajax.request({
+                     type: "POST",
+                     url: "..//liveRoom/update",
+                     contentType: "application/json",
+                     params: JSON.stringify(Object.assign(data,{
+                        enable:0
+                     })),
+                     successCallback: function () {
+                         alert('操作成功', function (index) {
+                             vm.reload();
+                         });
+                     }
+                 });
+             });
+         },
+         getInfo: function (id) {
+            vm.defaultList = []
+             Ajax.request({
+                 url: "../slideShow/getById?slideId=" + id,
+                 async: true,
+                 successCallback: function (r) {
+                     vm.carousel = r.page;
+                 }
+             });
+         },
+         reload: function (event) {
+             vm.showList = true;
+             var page = $("#jqGrid").jqGrid('getGridParam', 'page');
+             $("#jqGrid").jqGrid('setGridParam', {
+                 postData: {'name': vm.q.name},
+                 page: page
+             }).trigger("reloadGrid");
+             vm.handleReset('formValidate');
+         },
+         handleSuccessListPicUrl: function (res, file) {
+             vm.brand.listPicUrl = file.response.url;
+             vm.brand.appListPicUrl = file.response.url;
+         },
+         handleSuccessPicUrl: function (res, file) {
+             vm.brand.picUrl = file.response.url;
+         },
+         handleSuccessAppListPicUrl: function (res, file) {
+             vm.brand.appListPicUrl = file.response.url;
+         },
+         beforecoverImgUpload: function (file) {
+            this.loading = true
+            this.coverImg = URL.createObjectURL(file)
+         },
+         beforeShareImgUpload: function (file) {
+            this.loading = true
+            this.shareImg = URL.createObjectURL(file)
+         },
+         beforefeedsImgUpload: function (file) {
+            this.loading = true
+            this.feedsImg = URL.createObjectURL(file)
+         },
+
+         
+        handleSuccessShareImg: function (res, file) {
+            this.loading = false
+            this.broadcast.shareImg = file.response.msg;
+        },
+
+        handleSuccesscoverImg: function (res, file) {
+            this.loading = false
+            this.broadcast.coverImg = file.response.msg;
+        },
+
+        handleSuccessfeedsImg: function (res, file) {
+            this.loading = false
+            this.broadcast.feedsImg = file.response.msg;
+        },
+      
+        handleBefore(){
+            this.loading = true
+        },
+         handleSuccessNewPicUrl: function (res, file) {
+             vm.brand.newPicUrl = file.response.url;
+         },
+         handleFormatError: function (file) {
+            this.loading = false
+             this.$Notice.warning({
+                 title: '文件格式不正确',
+                 desc: '文件 ' + file.name + ' 格式不正确。'
+             });
+         },
+         handleMaxSize: function (file) {
+            this.loading = false
+             this.$Notice.warning({
+                 title: '超出文件大小限制',
+                 desc: '文件 ' + file.name + ' 太大。'
+             });
+         },
+         eyeImageListPicUrl: function () {
+             var url = vm.brand.listPicUrl;
+             eyeImage(url);
+         },
+         eyeImagePicUrl: function () {
+             var url = vm.brand.picUrl;
+             eyeImage(url);
+         },
+         eyeImageAppListPicUrl: function () {
+             var url = vm.brand.appListPicUrl;
+             eyeImage(url);
+         },
+         eyeImageNewPicUrl: function () {
+             var url = vm.brand.newPicUrl;
+             eyeImage(url);
+         },
+         handleSubmit: function (name) {
+             handleSubmitValidate(this, name, function () {
+                 vm.saveOrUpdate()
+             });
+         },
+         handleReset: function (name) {
+             handleResetForm(this, name);
+         }
+     },
+    mounted () {
+      
+    }
+  });

+ 236 - 0
js/shop/carousel.js

@@ -0,0 +1,236 @@
+$(function () {
+    var types = {
+     0:'服饰',
+     1:'家具',
+     2:'数码',
+     3:'娱乐',
+     4:'其他',
+    }
+     
+     $("#jqGrid").Grid({
+         url: '../slideShow/getAndQuery',
+         rownumWidth:60,
+         colModel: [{
+             label: 'id', name: 'id', index: 'slideId', key: true, hidden: true
+         }, 
+         {
+            label: 'slideId', name: 'slideId', index: 'slideId', hidden: true
+        }, 
+         {
+             label: '标题', name: 'title', index: 'title', width: 80
+         },
+         {
+            label: '封面图片',align:'center', name: 'coverImage', index: 'cover_image', width: 120, formatter: function (value) {
+                return transImg(value,100,'auto');
+            }
+        },
+         
+         {
+             label: '跳转链接', name: 'redirectUrl', index: 'redirect_url', width: 140,formatter: function (value) {
+                 if (value) {
+                    return '<span title="'+value+'">'+(value.length > 40 ?(value.substr(0,40) + '...'):value)+'</span>'
+                 }
+                 return ''
+            }
+         }, 
+         
+         {
+             label: '排序',align:'center', name: 'sortOrder', index: 'sort_order', width: 80
+         }, 
+         {
+            label: '更新人员', name: 'updater', index: 'updater', width: 80,formatter: function (value) {
+                return types[value] || '-'
+            }
+        }, 
+        {
+            label: '更新时间', name: 'updateTime', index: 'update_time', width: 80, formatter: function (value) {
+                return transDate(value, 'yyyy-MM-dd');
+            }
+        },
+         {
+             label: '显示',align:'center', name: 'isShow', index: 'is_show', width: 80, formatter: function (value) {
+                 return transIsNot(value)
+             }
+         },
+      
+     ]
+     });
+  });
+  
+  
+  const validateSceneUrlCheck = function (rule, value, callback){
+     var link1 ='https://test.4dkankan.com/eShopMobile.html?m='
+     var link2 ='https://www.4dkankan.com/eShopMobile.html?m='
+  
+     if (value === ''||!value) {
+         callback(new Error('场景地址不能为空'));
+     } else if(!~value.indexOf(link1)&&!~value.indexOf(link2)){
+         callback(new Error('场景地址需为'+link2+'或'+link1));
+     } else {
+         callback();
+     }
+  };
+
+  
+  var vm = new Vue({
+     el: '#rrapp',
+     data: {
+        loading:false,
+         showList: true,
+         title: null,
+         carousel: {title: '',coverImage:'',redirectUrl:'',order:'',updater:'', isShow: 1,remark:''},
+         ruleValidate: {
+            title: [
+                {required: true, message: '标题不能为空', trigger: 'blur'}
+            ],
+            coverImage: [
+                {required: true, message: '轮播图片不能为空', trigger: 'blur'}
+            ]
+         },
+         q: {
+             name: ''
+         }
+     },
+     methods: {
+        handleRemove (file) {
+            
+        },
+         query: function () {
+             vm.reload();
+         },
+         add: function () {
+             vm.showList = false;
+             vm.title = "新增";
+             vm.carousel =  {title: '',coverImage:'',redirectUrl:'',order:'',updater:'',remark:'', isShow: 1}
+         },
+         update: function (event) {
+             var data = getSelectedRowData("#jqGrid");
+             if (data.id == null) {
+                 return;
+             }
+             vm.showList = false;
+             vm.title = "修改";
+  
+             vm.getInfo(data.slideId)
+         },
+         saveOrUpdate: function (event) {
+             var url = vm.carousel.slideId == null ? "../slideShow/add" : "../slideShow/update";
+             Ajax.request({
+                 type: "POST",
+                 url: url,
+                 contentType: "application/json",
+                 params: JSON.stringify(vm.carousel),
+                 successCallback: function () {
+                     alert('操作成功', function (index) {
+                         vm.reload();
+                     });
+                 }
+             });
+         },
+         del: function (event) {
+             var ids = getSelectedRows("#jqGrid");
+             if (ids == null) {
+                 return;
+             }
+  
+             confirm('确定要删除选中的记录?', function () {
+  
+                 Ajax.request({
+                     type: "POST",
+                     url: "../brand/delete",
+                     contentType: "application/json",
+                     params: JSON.stringify(ids),
+                     successCallback: function () {
+                         alert('操作成功', function (index) {
+                             vm.reload();
+                         });
+                     }
+                 });
+             });
+         },
+         getInfo: function (id) {
+            vm.defaultList = []
+             Ajax.request({
+                 url: "../slideShow/getById?slideId=" + id,
+                 async: true,
+                 successCallback: function (r) {
+                     vm.carousel = r.page;
+                 }
+             });
+         },
+         reload: function (event) {
+             vm.showList = true;
+             var page = $("#jqGrid").jqGrid('getGridParam', 'page');
+             $("#jqGrid").jqGrid('setGridParam', {
+                 postData: {'name': vm.q.name},
+                 page: page
+             }).trigger("reloadGrid");
+             vm.handleReset('formValidate');
+         },
+         handleSuccessListPicUrl: function (res, file) {
+             vm.brand.listPicUrl = file.response.url;
+             vm.brand.appListPicUrl = file.response.url;
+         },
+         handleSuccessPicUrl: function (res, file) {
+             vm.brand.picUrl = file.response.url;
+         },
+         handleSuccessAppListPicUrl: function (res, file) {
+             vm.brand.appListPicUrl = file.response.url;
+         },
+         handleSuccessCarouselImage: function (res, file) {
+            this.loading = false
+            this.carousel.coverImage = file.response.url;
+        },
+      
+        handleBefore(){
+            this.loading = true
+        },
+         handleSuccessNewPicUrl: function (res, file) {
+             vm.brand.newPicUrl = file.response.url;
+         },
+         handleFormatError: function (file) {
+            this.loading = false
+             this.$Notice.warning({
+                 title: '文件格式不正确',
+                 desc: '文件 ' + file.name + ' 格式不正确。'
+             });
+         },
+         handleMaxSize: function (file) {
+            this.loading = false
+             this.$Notice.warning({
+                 title: '超出文件大小限制',
+                 desc: '文件 ' + file.name + ' 太大。'
+             });
+         },
+         eyeImageListPicUrl: function () {
+             var url = vm.brand.listPicUrl;
+             eyeImage(url);
+         },
+         eyeImagePicUrl: function () {
+             var url = vm.brand.picUrl;
+             eyeImage(url);
+         },
+         eyeImageAppListPicUrl: function () {
+             var url = vm.brand.appListPicUrl;
+             eyeImage(url);
+         },
+         eyeImageNewPicUrl: function () {
+             var url = vm.brand.newPicUrl;
+             eyeImage(url);
+         },
+         handleSubmit: function (name) {
+             console.log('====================================');
+             console.log(name);
+             console.log('====================================');
+             handleSubmitValidate(this, name, function () {
+                 vm.saveOrUpdate()
+             });
+         },
+         handleReset: function (name) {
+             handleResetForm(this, name);
+         }
+     },
+    mounted () {
+      
+    }
+  });

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 4814 - 0
js/shop/city.js


+ 228 - 60
js/shop/coupon.js

@@ -1,47 +1,38 @@
+let cacheData = {
+}
 $(function () {
     $("#jqGrid").Grid({
         url: '../coupon/list',
         rownumWidth:60,
+        loadComplete: function(){
+            var re_records = $("#list").getGridParam('records');
+            if(re_records == 0 || re_records == null){
+            if($(".norecords").html() == null){
+            $("#list").parent().append("<div class=\"norecords\">没有符合数据</div>");
+            }
+            $(".norecords").show();
+            }
+        },
         colModel: [
             {label: 'id', name: 'id', index: 'id', key: true, hidden: true},
+            {label: '店铺名称', name: 'brandName', index: 'brandName', width: 120},
             {label: '优惠券名称', name: 'name', index: 'name', width: 120},
-            {label: '金额', name: 'typeMoney', index: 'type_money', width: 80},
             {
-                label: '发放方式', name: 'sendType', index: 'send_type', width: 80, formatter: function (value) {
+                label: '发放类型', name: 'sendType', index: 'send_type', width: 80, formatter: function (value) {
                     if (value == 0) {
-                        return '按订单发放';
+                        return '全场赠券';
                     } else if (value == 1) {
-                        return '按用户发放';
+                        return '会员赠券';
                     } else if (value == 2) {
-                        return '商品转发送券';
+                        return '购物赠券';
                     } else if (value == 3) {
-                        return '按商品发放';
-                    } else if (value == 4) {
-                        return '新用户注册';
-                    } else if (value == 5) {
-                        return '线下发放';
-                    } else if (value == 7) {
-                        return '包邮优惠';
+                        return '注册赠券';
                     }
                     return '-';
                 }
             },
-            {label: '最小金额', name: 'minAmount', index: 'min_amount', width: 80},
-            {label: '最大金额', name: 'maxAmount', index: 'max_amount', width: 80},
-            {
-                label: '发放开始时间',
-                name: 'sendStartDate',
-                index: 'send_start_date',
-                width: 120,
-                formatter: function (value) {
-                    return transDate(value);
-                }
-            },
-            {
-                label: '发放结束时间', name: 'sendEndDate', index: 'send_end_date', width: 120, formatter: function (value) {
-                    return transDate(value);
-                }
-            },
+            {label: '优惠券面额(元)', name: 'typeMoney', index: 'type_money', width: 80},
+            {label: '最低消费额(元)', name: 'minGoodsAmount', index: 'min_goods_amount', width: 80},
             {
                 label: '使用开始时间',
                 name: 'useStartDate',
@@ -56,13 +47,34 @@ $(function () {
                     return transDate(value);
                 }
             },
-            {label: '最小商品金额', name: 'minGoodsAmount', index: 'min_goods_amount', width: 80},
+            {label: '发放数量', name: 'number', index: 'number', width: 80},
+            {label: '已领取数量', name: 'receiveNumber', index: 'receive_number', width: 80},
+            {label: '优惠券状态', name: 'couponStatus', index: 'coupon_status', width: 80,
+                formatter: function (value) {
+                    if (value == 4) {
+                        return '停止发放';
+                    } else if (value == 1) {
+                        return '未生效';
+                    } else if (value == 2) {
+                        return '生效中';
+                    } else if (value == 3) {
+                        return '已失效';
+                    }
+                    return '-';
+            }},
             {
-                label: '操作', width: 70, sortable: false, formatter: function (value, col, row) {
-                    if (row.sendType == 1 || row.sendType == 3) {
-                        return '<button class="ivu-btn ivu-btn-primary ivu-btn-circle ivu-btn-small" onclick="vm.publish(' + row.id + ',' + row.sendType + ')"><i class="ivu-icon ivu-icon-android-send"></i>发放</button>';
+                label: '操作', width: 100,  align:'center', sortable: false, formatter: function (value, col, row) {
+                    cacheData[col.rowId] = row
+                    let name = ''
+                    if (row.couponStatus == 2) {
+                        name = '停止'
+                    }
+                    if (row.couponStatus == 4) {
+                        name = '恢复'
                     }
-                    return '';
+                    let view = '<button class="btn btn-outline btn-info" onclick="vm.lookDetail(' + col.rowId + ');event.cancelBubble=true;"><i></i>&nbsp;查看</button>'
+                    let recover = '<button class="btn btn-outline btn-primary" style="margin-left:10px;" onclick="vm.changeStatus(' + col.rowId + ');event.cancelBubble=true;"><i></i>&nbsp;'+name+'</button>'
+                    return view + (name&&recover);
                 }
             }]
     });
@@ -70,26 +82,102 @@ $(function () {
 
 var vm = new Vue({
     el: '#rrapp',
-    data: {
-        showList: true,
-        showCard: false,
-        showGoods: false,
-        title: null,
-        coupon: {sendType: 0},
-        ruleValidate: {
-            name: [
-                {required: true, message: '优惠券名称不能为空', trigger: 'blur'}
-            ]
-        },
-        q: {
-            name: ''
-        },
-        goods: [],
-        goodss: [],
-        user: [],
-        users: [],
-        selectData: {},
-        sendSms: ''//是否发送短信
+    data(){
+        const validateBrandIdCheck =function (rule, value, callback)  {
+            if (value === '' || !value) {
+                callback(new Error('店铺不能为空'));
+            }else {
+                callback();
+            }
+        };
+
+        const validateNameCheck =function (rule, value, callback) {
+            if (value === '' || !value ) {
+                callback(new Error('优惠券名称不能为空'));
+            } 
+            else if(value.length>20){
+                callback(new Error('优惠券名称不能超过20个字符'));
+            }
+            else {
+                callback();
+            }
+        };
+
+        const validateDescCheck =function (rule, value, callback) {
+            if (value === '' || !value ) {
+                callback(new Error('使用说明不能为空'));
+            } 
+            else if(value.length>200){
+                callback(new Error('使用说明不能超过200个字符'));
+            }
+            else {
+                callback();
+            }
+        };
+
+        const validateNotNullIdCheck =function (rule, value, callback)  {
+            if (value === '' || !value) {
+                callback(new Error(rule.name+'不能为空'));
+            }else {
+                callback();
+            }
+        };
+        return {
+            showList: true,
+            showCard: false,
+            showGoods: false,
+            title: null,
+            coupon: {
+                sendType: 0,
+                brandId:'',
+                brandName:'',
+                name:'',
+                typeMoney:'',
+                minGoodsAmount:'',
+                number:'',
+                useStartDate:'',
+                useEndDate:'',
+                useDesc:'',
+            },
+            ruleValidate: {
+                name: [
+                    {required: true, validator: validateNameCheck, trigger: 'blur'}
+                ],
+                brandId: [
+                    {required: true, validator: validateBrandIdCheck, trigger: 'change'}
+                ],
+                typeMoney: [
+                    {required: true,name:'面值金额', validator: validateNotNullIdCheck, trigger: 'change'}
+                ],
+                minGoodsAmount: [
+                    {required: true,name:'最小订单金额', validator: validateNotNullIdCheck, trigger: 'change'}
+                ],
+                number: [
+                    {required: true, name: '发放数量',validator: validateNotNullIdCheck,  trigger: 'change'}
+                ],
+                useStartDate: [
+                    {required: true, name: '使用开始时间',validator: validateNotNullIdCheck,  trigger: 'change'}
+                ],
+                useEndDate: [
+                    {required: true, name: '使用结束时间',validator: validateNotNullIdCheck,  trigger: 'change'}
+                ],
+                useDesc: [
+                    {required: true, validator: validateDescCheck,trigger: 'blur'}
+                ],
+            },
+            q: {
+                name: '',
+                couponStatus: ' ',
+                brandName: ''
+            },
+            goods: [],
+            goodss: [],
+            brands:[],
+            user: [],
+            users: [],
+            selectData: {},
+            sendSms: ''//是否发送短信
+        }
     },
     methods: {
         query: function () {
@@ -100,7 +188,20 @@ var vm = new Vue({
             vm.showCard = true;
             vm.showGoods = false;
             vm.title = "新增";
-            vm.coupon = {sendType: 0};
+            vm.coupon = {
+                sendType: 0,
+                brandId:'',
+                brandName:'',
+                name:'',
+                typeMoney:'',
+                minGoodsAmount:'',
+                number:'',
+                useStartDate:'',
+                useEndDate:'',
+                useDesc:''
+            };
+            
+            vm.getBrands();
         },
         update: function (event) {
             var id = getSelectedRow("#jqGrid");
@@ -111,18 +212,25 @@ var vm = new Vue({
             vm.showCard = true;
             vm.showGoods = false;
             vm.title = "修改";
-
+            vm.getBrands();
             vm.getInfo(id)
         },
         saveOrUpdate: function (event) {
+            if (vm.coupon.minGoodsAmount < vm.coupon.typeMoney) {
+                return alert('面值金额 需小于 最小订单金额,才可新增优惠券')
+            }
             var url = vm.coupon.id == null ? "../coupon/save" : "../coupon/update";
-
+            vm.brands.forEach(item=>{
+                if (item.id == vm.coupon.brandId) {
+                    vm.coupon.brandName = item.name
+                }
+            })
             Ajax.request({
                 type: "POST",
                 url: url,
                 contentType: "application/json",
                 params: JSON.stringify(vm.coupon),
-                successCallback: function (r) {
+                successCallback: function () {
                     alert('操作成功', function (index) {
                         vm.reload();
                     });
@@ -138,9 +246,11 @@ var vm = new Vue({
             confirm('确定要删除选中的记录?', function () {
                 Ajax.request({
                     type: "POST",
-                    url: "../coupon/delete",
+                    url: "../coupon/deleteCoupons",
                     contentType: "application/json",
-                    params: JSON.stringify(ids),
+                    params: JSON.stringify({
+                        idList: ids
+                    }),
                     successCallback: function (r) {
                         alert('操作成功', function (index) {
                             vm.reload();
@@ -158,13 +268,33 @@ var vm = new Vue({
                 }
             });
         },
+        
+        getBrands: function () {
+            Ajax.request({
+                url: "../brand/queryAll",
+                async: true,
+                successCallback: function (r) {
+                    vm.brands = r.list;
+                    r.list.forEach(item=>{
+                        if (item.id == vm.coupon.brandId) {
+                            vm.coupon.brandName = item.name
+                        }
+                    })
+                }
+            });
+        },
         reload: function (event) {
+            this.getBrands();
             vm.showList = true;
             vm.showCard = false;
             vm.showGoods = false;
             var page = $("#jqGrid").jqGrid('getGridParam', 'page');
             $("#jqGrid").jqGrid('setGridParam', {
-                postData: {'name': vm.q.name},
+                postData: {
+                    'name': vm.q.name,
+                    'brandName': vm.q.brandName,
+                    'couponStatus': vm.q.couponStatus
+                },
                 page: page
             }).trigger("reloadGrid");
             vm.handleReset('formValidate');
@@ -200,6 +330,41 @@ var vm = new Vue({
                 }
             });
         },
+        lookDetail:function (rowId) {
+            let id = cacheData[rowId].id
+            let brandName = cacheData[rowId].brandName
+            let name = cacheData[rowId].name
+
+
+            if (id == null) {
+                return;
+            }
+            
+            openWindow({
+                title: '优惠券明细',
+                type: 2,
+                content: '../shop/coupondetail.html?couponId=' + id + '&brandName=' + brandName +'&name=' + name
+            })
+            return false
+        },
+        changeStatus:function (rowId) {
+            let row = cacheData[rowId]
+            let msg = row.couponStatus == 2?'停止后,优惠券将不再发放,是否继续?':'恢复后,优惠券将允许发放,是否继续?'
+            confirm(msg, function () {
+                vm.coupon.couponStatus = row.couponStatus == 2?4:2
+
+                Ajax.request({
+                    url: '../coupon/updateStatus?status='+(row.couponStatus == 2?4:2)+'&couponId='+row.id,
+                    contentType: "application/json",
+                    successCallback: function (r) {
+                        alert('操作成功', function (index) {
+                            vm.reload();
+                        });
+                    }
+                });
+            })
+
+        },
         publishSubmit: function () {
 
             var sendType = vm.selectData.sendType;
@@ -243,5 +408,8 @@ var vm = new Vue({
                 }
             });
         }
+    },
+    mounted:function() {
+        this.getBrands()
     }
 });

+ 184 - 0
js/shop/coupondetail.js

@@ -0,0 +1,184 @@
+let cacheData = {
+}
+var brandName =  getQueryString("brandName");
+var couponname =  getQueryString("name");
+
+$(function () {
+    let couponId = getQueryString("couponId");
+    
+    let url = '../coupon/useDetailList';
+    if (couponId) {
+        url += '?couponId=' + couponId;
+    }
+    $("#jqGrid").Grid({
+        url: url,
+        rownumWidth:60,
+        
+        loadComplete:function()
+        {
+            var rowNum = $("#jqGrid").find('.jqgrow').length;
+            if(!rowNum)
+            {
+                if(!$("#emptyRecords").html())
+                {
+                    $("#jqGrid").append('<div id="emptyRecords" style="width:100%; height:200px;  text-align:center;">'
+                            +'<div style="width:220px; height:100px; padding-top:40px; clear:both; margin:0 auto ;position: absolute;top: 190px;left: 50%;transform: translateX(-50%);">'
+                            +'<div>暂无人领取优惠券</div>'
+                            +'</div></div>');
+                    console.log('wwwww',$("#gridTable").parent());
+
+                }
+                $("#emptyRecords").show();
+            }
+            else
+            {
+                $("#emptyRecords").hide();
+            }
+        },
+        colModel: [
+            {label: 'idx', name: 'idx', index: 'id', key: true, hidden: true},
+            {label: '优惠券编码', name: 'couponSn', index: 'coupon_sn', width: 80},
+            {
+                label: '发放类型', name: 'sendType', index: 'send_type', width: 80, formatter: function (value) {
+                    if (value == 0) {
+                        return '全场赠券';
+                    } else if (value == 1) {
+                        return '会员赠券';
+                    } else if (value == 2) {
+                        return '购物赠券';
+                    } else if (value == 3) {
+                        return '注册赠券';
+                    }
+                    return '-';
+                }
+            },
+            {label: '订单号', name: 'orderSn', index: 'order_sn', width: 80},
+            {label: '会员编码', name: 'userId', index: 'user_id', width: 80},
+            {label: '会员名称', name: 'userName', index: 'user_name', width: 80},
+            {label: '使用状态', name: 'useStatus', index: 'use_status', width: 80,
+                formatter: function (value) {
+                    if (value == 1) {
+                        return '已领取';
+                    } else if (value == 2) {
+                        return '已使用';
+                    } else if (value == 3) {
+                        return '已过期';
+                    } else if (value == 4) {
+                        return '已作废';
+                    }
+                    return '-';
+            }},
+            {label: '状态变更时间', name: 'updateTime', index: 'update_time', width: 80},
+            {
+                label: '操作', width: 100,  align:'center', sortable: false, formatter: function (value, col, row) {
+                    cacheData[col.rowId] = row
+                    if (row.useStatus == 1) {
+                        return '<button class="btn btn-outline btn-warning" onclick="vm.void(' + col.rowId + ');event.cancelBubble=true;"><i></i>&nbsp;作废</button>'
+                    }
+                    return '';
+            }
+        }]
+    });
+});
+
+var vm = new Vue({
+    el: '#rrapp',
+    data: {
+        showList: true,
+        title: null,
+        userCoupon: {},
+        q: {
+            userName: '',
+            couponName: ''
+        },
+        brandName:brandName,
+        name:couponname
+    },
+    methods: {
+        query: function () {
+            vm.reload();
+        },
+        add: function () {
+            vm.showList = false;
+            vm.title = "新增";
+            vm.userCoupon = {};
+        },
+        update: function (event) {
+            var id = getSelectedRow("#jqGrid");
+            if (id == null) {
+                return;
+            }
+            vm.showList = false;
+            vm.title = "修改";
+
+            vm.getInfo(id)
+        },
+        saveOrUpdate: function (event) {
+            var url = vm.userCoupon.id == null ? "../usercoupon/save" : "../usercoupon/update";
+
+            Ajax.request({
+                type: "POST",
+                url: url,
+                contentType: "application/json",
+                params: JSON.stringify(vm.userCoupon),
+                successCallback: function (r) {
+                    alert('操作成功', function (index) {
+                        vm.reload();
+                    });
+                }
+            });
+        },
+        void: function (rowId) {
+            let row = cacheData[rowId]
+            let msg = '作废后,优惠券将无法使用,是否继续?'
+            confirm(msg, function () {
+                Ajax.request({
+                    url: '../usercoupon/cancelUserCoupon?userId='+row.userId+'&couponId='+row.id,
+                    contentType: "application/json",
+                    successCallback: function (r) {
+                        alert('操作成功', function (index) {
+                            vm.reload();
+                        });
+                    }
+                });
+            })
+        },
+        del: function (event) {
+            var ids = getSelectedRows("#jqGrid");
+            if (ids == null) {
+                return;
+            }
+            confirm('确定要删除选中的记录?', function () {
+
+                Ajax.request({
+                    type: "POST",
+                    url: "../usercoupon/delete",
+                    contentType: "application/json",
+                    params: JSON.stringify(ids),
+                    successCallback: function (r) {
+                        alert('操作成功', function (index) {
+                            vm.reload();
+                        });
+                    }
+                });
+            });
+        },
+        getInfo: function (id) {
+            Ajax.request({
+                url: "../usercoupon/info/" + id,
+                async: true,
+                successCallback: function (r) {
+                    vm.userCoupon = r.userCoupon;
+                }
+            });
+        },
+        reload: function (event) {
+            vm.showList = true;
+            var page = $("#jqGrid").jqGrid('getGridParam', 'page');
+            $("#jqGrid").jqGrid('setGridParam', {
+                postData: {'userName': vm.q.userName, 'couponName': vm.q.couponName},
+                page: page
+            }).trigger("reloadGrid");
+        }
+    }
+});

+ 62 - 4
js/shop/goods.js

@@ -5,6 +5,8 @@ $(function () {
         colModel: [
             {label: 'id', name: 'id', index: 'id', key: true, hidden: true},
             {label: '商品名称', name: 'name', index: 'name', width: 160},
+            {label: '商品描述', name: 'goodsSimpleDesc', index: 'goodsSimpleDesc', width: 160},
+            {label: '购买链接', name: 'realShopUrl', index: 'realShopUrl', width: 160},
             {label: '商品分类', name: 'categoryName', index: 'category_id', width: 80},
             {label: '店铺名称', name: 'brandName', index: 'brand_id', width: 120},
             {
@@ -141,6 +143,47 @@ var vm = new Vue({
                 callback();
             }
         };
+
+        const validateNameCheck =function (rule, value, callback) {
+            if (value === '' || !value ) {
+                callback(new Error('名称不能为空'));
+            } 
+            else if(value.length>15){
+                callback(new Error('商品名称不能超过15个字符'));
+            }
+            else {
+                callback();
+            }
+        };
+
+        const validaterealShopUrlCheck =function (rule, value, callback) {
+            if (value === '' || !value ) {
+                callback();
+            } 
+            else if(value.length>500){
+                callback(new Error('网站链接不能超过500个字符'));
+            }
+            else if(!(value.indexOf('item.jd.com')>-1||value.indexOf('item.m.jd.com')>-1)){
+                callback(new Error('目前不支持添加其他网站链接'));
+            }
+            
+            else {
+                callback();
+            }
+        };
+        
+
+        const validateDescCheck =function (rule, value, callback) {
+            if (value === '' || !value ) {
+                callback(new Error('商品描述不能为空'));
+            } 
+            else if(value.length>30){
+                callback(new Error('商品描述不能超过30个字符'));
+            }
+            else {
+                callback();
+            }
+        };
         return {
             ggheader:guigeDetailHeader,
             ggContent:'',
@@ -155,6 +198,7 @@ var vm = new Vue({
                 categoryId: '',
                 isOnSale: 1,
                 isNew: 1,
+                realShopUrl:'',
                 isAppExclusive: 0,
                 isLimited: 0,
                 isHot: 0,
@@ -169,7 +213,13 @@ var vm = new Vue({
                     {required: true, message: '商品序列号不能为空', trigger: 'blur'}
                 ],
                 name: [
-                    {required: true, message: '名称不能为空', trigger: 'blur'}
+                    {required: true, validator: validateNameCheck, trigger: 'blur'}
+                ],
+                goodsSimpleDesc: [
+                    {required: true, validator: validateDescCheck, trigger: 'blur'}
+                ],
+                realShopUrl: [
+                    {validator: validaterealShopUrlCheck, trigger: 'blur'}
                 ],
                 brandId: [
                     {required: true, validator: validateBrandIdCheck, trigger: 'change'}
@@ -316,7 +366,6 @@ var vm = new Vue({
             let itm = []
             let goodsSpecificationList = []
             this.ggname = []
-            console.log(this.guigeArr)
             this.guigeArr.forEach(function(item,idx){
                 itm = []
                 item.val.forEach(function(sub,i){
@@ -332,6 +381,7 @@ var vm = new Vue({
                             marketPrice:''
                         }
                     }
+                    sub.uuid = sub.uuid||((idx+1)+'-'+(i+1))
                     itm.push(tt)
                     goodsSpecificationList.push(tt)
                 })
@@ -340,6 +390,8 @@ var vm = new Vue({
                 })
                 tmp.push(itm)
             })
+            console.log(this.guigeArr)
+
 
             tmp[0].forEach(function (i1){
                 if (tmp[1]) {
@@ -454,7 +506,7 @@ var vm = new Vue({
                     }
                 ]
             }]
-            vm.ggContent='',
+            vm.ggContent=''
             vm.currenIdx=''
             vm.currenI=''
             vm.inputArr=[]
@@ -489,6 +541,11 @@ var vm = new Vue({
                 async: true,
                 successCallback: function (r) {
                     vm.brands = r.list;
+                    r.list.forEach(item=>{
+                        if (item.id == vm.goods.brandId) {
+                            vm.goods.brandName = item.name
+                        }
+                    })
                 }
             });
         },
@@ -528,7 +585,7 @@ var vm = new Vue({
 
             vm.goods.goodsImgList = vm.uploadList;
 
-            vm.goods['goodsSpecificationList'] = vm.goodsSpecificationList
+            vm.goods['goodsSpecificationList'] = vm.goods.id == null ?vm.guigeArr: vm.goodsSpecificationList
             vm.goods['productList'] = vm.inputArr
 
             vm.goods['guigeArr'] = JSON.stringify(vm.guigeArr)
@@ -550,6 +607,7 @@ var vm = new Vue({
                     }
                 }
             })
+
             Ajax.request({
                 type: "POST",
                 url: url,