فهرست منبع

'0706-2336-01'

zory 1 روز پیش
والد
کامیت
38f4277292
28فایلهای تغییر یافته به همراه4279 افزوده شده و 31 حذف شده
  1. 37 23
      src/api/model/goods.js
  2. 54 0
      src/api/model/plan.js
  3. 33 0
      src/api/model/star.js
  4. 1 1
      src/config/index.js
  5. 1 1
      src/layout/index.vue
  6. 1 1
      src/views/manage/components/password.vue
  7. 358 0
      src/views/manage/cps/index/components/edit.vue
  8. 362 0
      src/views/manage/cps/index/components/form.vue
  9. 75 0
      src/views/manage/cps/index/components/option.vue
  10. 79 0
      src/views/manage/cps/index/components/search.vue
  11. 213 0
      src/views/manage/cps/index/components/table.vue
  12. 47 0
      src/views/manage/cps/index/index.vue
  13. 80 0
      src/views/manage/cps/star/components/form.vue
  14. 75 0
      src/views/manage/cps/star/components/option.vue
  15. 77 0
      src/views/manage/cps/star/components/search.vue
  16. 218 0
      src/views/manage/cps/star/components/table.vue
  17. 47 0
      src/views/manage/cps/star/index.vue
  18. 13 0
      src/views/manage/finance/open/index.vue
  19. 85 0
      src/views/manage/goods/index/components/form.vue
  20. 75 0
      src/views/manage/goods/index/components/option.vue
  21. 81 0
      src/views/manage/goods/index/components/search.vue
  22. 200 0
      src/views/manage/goods/index/components/table.vue
  23. 45 1
      src/views/manage/goods/index/index.vue
  24. 881 0
      src/views/manage/goods/op/add.vue
  25. 254 0
      src/views/manage/goods/op/components/sku.vue
  26. 872 0
      src/views/manage/goods/op/edit.vue
  27. 7 3
      src/views/manage/setting/basic/index.vue
  28. 8 1
      src/views/merchant/finance/index/components/form.vue

+ 37 - 23
src/api/model/goods.js

@@ -3,45 +3,59 @@ import http from "@/utils/request";
 
 
 export default {
 export default {
     list: {
     list: {
-        url: `${config.API_URL}/store/list`,
+        url: `${config.API_URL}/goods/list`,
         name: "-",
         name: "-",
-        get: async function (data = {}) {
-            return await http.get(this.url, data);
+        get: async function (params) {
+            return await http.get(this.url, params);
         },
         },
     },
     },
-    save: {
-        url: `${config.API_URL}/store/save`,
+    category: {
+        url: `${config.API_URL}/category/list`,
         name: "-",
         name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
+        get: async function (params) {
+            return await http.get(this.url, params);
         },
         },
     },
     },
-    edit: {
-        url: `${config.API_URL}/store/edit`,
+    detail: {
+        url: `${config.API_URL}/goods/detail`,
         name: "-",
         name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
+        get: async function (params) {
+            return await http.get(this.url, params);
         },
         },
     },
     },
-    batch: {
-        url: `${config.API_URL}/store/batch`,
+    type: {
+        url: `${config.API_URL}/goods/type`,
+        name: "-",
+        get: async function (params) {
+            return await http.get(this.url, params);
+        },
+    },
+    save: {
+        url: `${config.API_URL}/goods/save`,
         name: "-",
         name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
+        post: async function (params) {
+            return await http.post(this.url, params);
         },
         },
     },
     },
-    sync: {
-        url: `${config.API_URL}/store/sync`,
+    template: {
+        url: `${config.API_URL}/goods/template`,
         name: "-",
         name: "-",
-        get: async function (data = {}) {
-            return await http.get(this.url, data);
+        post: async function (params) {
+            return await http.post(this.url, params);
         },
         },
     },
     },
-    del: {
-        url: `${config.API_URL}/store/del`,
+    off: {
+        url: `${config.API_URL}/goods/off`,
+        name: "-",
+        post: async function (params) {
+            return await http.post(this.url, params);
+        },
+    },
+    batch: {
+        url: `${config.API_URL}/goods/batch`,
         name: "-",
         name: "-",
-        post: async function (data = {}) {
-            return await http.post(this.url, data);
+        post: async function (params) {
+            return await http.post(this.url, params);
         },
         },
     },
     },
 }
 }

+ 54 - 0
src/api/model/plan.js

@@ -0,0 +1,54 @@
+import config from "@/config";
+import http from "@/utils/request";
+
+export default {
+    list: {
+        url: `${config.API_URL}/plan/list`,
+        name: "-",
+        get: async function (params) {
+            return await http.get(this.url, params);
+        },
+    },
+    detail: {
+        url: `${config.API_URL}/plan/detail`,
+        name: "-",
+        get: async function (params) {
+            return await http.get(this.url, params);
+        },
+    },
+    close: {
+        url: `${config.API_URL}/plan/close`,
+        name: "-",
+        post: async function (params) {
+            return await http.post(this.url, params);
+        },
+    },
+    save: {
+        url: `${config.API_URL}/plan/save`,
+        name: "-",
+        post: async function (params) {
+            return await http.post(this.url, params);
+        },
+    },
+    goods: {
+        url: `${config.API_URL}/plan/goods`,
+        name: "-",
+        post: async function (params) {
+            return await http.post(this.url, params);
+        },
+    },
+    update: {
+        url: `${config.API_URL}/plan/update`,
+        name: "-",
+        post: async function (params) {
+            return await http.post(this.url, params);
+        },
+    },
+    del: {
+        url: `${config.API_URL}/plan/del`,
+        name: "-",
+        post: async function (params) {
+            return await http.post(this.url, params);
+        },
+    },
+}

+ 33 - 0
src/api/model/star.js

@@ -0,0 +1,33 @@
+import config from "@/config";
+import http from "@/utils/request";
+
+export default {
+    list: {
+        url: `${config.API_URL}/star/list`,
+        name: "-",
+        get: async function (params) {
+            return await http.get(this.url, params);
+        },
+    },
+    save: {
+        url: `${config.API_URL}/star/save`,
+        name: "-",
+        post: async function (params) {
+            return await http.post(this.url, params);
+        },
+    },
+    update: {
+        url: `${config.API_URL}/star/update`,
+        name: "-",
+        post: async function (params) {
+            return await http.post(this.url, params);
+        },
+    },
+    del: {
+        url: `${config.API_URL}/star/del`,
+        name: "-",
+        post: async function (params) {
+            return await http.post(this.url, params);
+        },
+    },
+}

+ 1 - 1
src/config/index.js

@@ -31,7 +31,7 @@ const DEFAULT_CONFIG = {
 
 
 	//布局 默认:default | 通栏:header | 经典:menu | 功能坞:dock
 	//布局 默认:default | 通栏:header | 经典:menu | 功能坞:dock
 	//dock将关闭标签和面包屑栏
 	//dock将关闭标签和面包屑栏
-	LAYOUT: 'default',
+	LAYOUT: 'header',
 
 
 	//菜单是否折叠
 	//菜单是否折叠
 	MENU_IS_COLLAPSE: false,
 	MENU_IS_COLLAPSE: false,

+ 1 - 1
src/layout/index.vue

@@ -22,7 +22,7 @@
 			</div>
 			</div>
 		</header>
 		</header>
 		<section class="aminui-wrapper">
 		<section class="aminui-wrapper">
-			<sc-water-mark ref="wm" :text="userName" :subtext="dateTime" color="rgba(228, 231, 237,0.5)">
+			<sc-water-mark ref="wm" :text="userName" :subtext="dateTime" color="rgba(228, 231, 237,0.3)">
 				<div v-if="nextMenu.length > 0 || !pmenu.component"
 				<div v-if="nextMenu.length > 0 || !pmenu.component"
 					:class="menuIsCollapse ? 'aminui-side isCollapse' : 'aminui-side'">
 					:class="menuIsCollapse ? 'aminui-side isCollapse' : 'aminui-side'">
 					<div v-if="!menuIsCollapse" class="adminui-side-top">
 					<div v-if="!menuIsCollapse" class="adminui-side-top">

+ 1 - 1
src/views/manage/components/password.vue

@@ -71,7 +71,7 @@ export default{
             this.$refs.dialogForm.validate(async (valid) => {
             this.$refs.dialogForm.validate(async (valid) => {
                 if (valid) {
                 if (valid) {
                     let password = this.$TOOL.crypto.MD5(this.formData.password);
                     let password = this.$TOOL.crypto.MD5(this.formData.password);
-                    var result = await this.$API.user.pwd.post({password:password,id:this.formData.id});
+                    var result = await this.$API.user.pwd.post({password:password,id:this.formData.username});
                     if(result.code !== 1){
                     if(result.code !== 1){
                         this.$message.warning(result.msg)
                         this.$message.warning(result.msg)
                         this.isSaveing = false;
                         this.isSaveing = false;

+ 358 - 0
src/views/manage/cps/index/components/edit.vue

@@ -0,0 +1,358 @@
+<template>
+    <el-drawer v-model="visible" size="800px" destroy-on-close :close-on-click-modal="false" :with-header="false">
+        <el-container class="flex-column">
+            <div class="drawer-detail-main">
+                <div class="drawer-detail-header">
+                    <div class="drawer-detail-header-body">
+                        <div class="drawer-detail-header-left">{{titleMap[mode]}}</div>
+                        <div class="drawer-detail-header-left">
+                            <el-button type="default" icon="el-icon-close" @click="visible=false"></el-button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <el-main>
+                <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
+                    <el-form-item label="计划名称" prop="plan_name">
+                        <el-input v-model="formData.plan_name" readonly disabled clearable placeholder="请输入"></el-input>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                    <el-form-item label="推广团购商品" v-if="mode == 'goods'">
+                        <div class="flex-loading" v-if="loading && goodsData.length == 0">
+                            <el-card shadow="never">
+                                <el-skeleton :rows="5" animated></el-skeleton>
+                            </el-card>
+                            <el-card shadow="never" style="margin-top: 15px;">
+                                <el-skeleton animated></el-skeleton>
+                            </el-card>
+                        </div>
+                        <el-button type="default" @click="quickGoods" v-if="goodsData.length > 0">一键设置佣金</el-button>
+                        <div class="goods-live" v-if="goodsData.length>0">
+                            <scTable ref="starTable" :data="goodsData" row-key="id" height="500" hidePagination hideDo style="width: 750px;">
+                                <el-table-column label="商品信息" width="340" prop="name" fixed="left">
+                                    <template #default="scope">
+                                        <div class="goods-img">
+                                            <div class="img">
+                                                <el-image 
+                                                style="width: 54px; height: 54px"
+                                                :src="scope.row.goods.image_list[0].url"
+                                                :zoom-rate="1.2"
+                                                :max-scale="7"
+                                                :min-scale="0.2"
+                                                :preview-src-list="[scope.row.goods.image_list[0].url]"
+                                                preview-teleported
+                                                z-index="999"
+                                                fit="cover"></el-image>
+                                            </div>
+                                            <div class="name">
+                                                <span>{{ scope.row.goods.product_name }}</span>
+                                                <span class="dec">商品编码:{{ scope.row.goods.product_id }}</span>
+                                            </div>
+                                        </div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="佣金比例" prop="types" width="150">
+                                    <template #default="scope">
+                                        <el-input v-model="scope.row.commission_rate" @input="setRate(scope.$index)" @focus="setRate(scope.$index)" placeholder="0%-29%">
+                                            <template #suffix>%</template>
+                                        </el-input>
+                                        <div class="el-form-item-msg">预估每单佣金 {{ scope.row.rate_money }}</div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="商品类型" prop="types" width="100">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.goods.types">{{ scope.row.goods.types }}</span>
+                                        <span v-else>不限</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="价格" width="200" prop="id">
+                                    <template #default="scope">
+                                        <div class="price">{{ $TOOL.moneyFormat(scope.row.goods.price) }}</div>
+                                        <div class="goods-price">
+                                            <div class="del">{{ $TOOL.moneyFormat(scope.row.goods.line_price) }}</div>
+                                            <span>{{ $TOOL.disFormat(scope.row.goods.price,scope.row.goods.line_price) }}折</span></div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="剩余库存" prop="category_id" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.goods.limit_use_rule==1">{{ scope.row.goods.use_num_per_consume }}</span>
+                                        <span v-else>不限</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="状态" prop="enable" width="120" align="center">
+                                    <template #default="scope">
+                                        <div class="status-success" v-if="scope.row.goods.status==1"><sc-status-indicator type="success"></sc-status-indicator> 正常</div>
+                                        <div class="status-danger" v-if="scope.row.goods.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 禁用</div>
+                                        <div class="status-danger" v-if="scope.row.goods.status==0"><sc-status-indicator type="danger"></sc-status-indicator> 审核中</div>
+                                    </template>
+                                </el-table-column>
+                            </scTable>
+                        </div>
+                    </el-form-item>
+                    <el-form-item label="指定带货达人" v-if="mode == 'star'">
+                        <el-button type="default" @click="addStar" v-if="starData.length>0">添加达人({{ starData.length }}/200)</el-button>
+                        <div class="flex-loading" v-if="loading && starData.length == 0">
+                            <el-card shadow="never">
+                                <el-skeleton :rows="5" animated></el-skeleton>
+                            </el-card>
+                            <el-card shadow="never" style="margin-top: 15px;">
+                                <el-skeleton animated></el-skeleton>
+                            </el-card>
+                        </div>
+                        <div class="goods-live" v-if="starData.length>0">
+                            <scTable ref="starTable" :data="starData" row-key="id" height="500" hidePagination hideDo style="width: 750px;">
+                                <el-table-column label="达人" width="340" prop="name" fixed="left">
+                                    <template #default="scope">
+                                        <div class="goods-img">
+                                            <div class="img">
+                                                <el-image 
+                                                style="width: 54px; height: 54px"
+                                                :src="scope.row.star.avatar_url"
+                                                :zoom-rate="1.2"
+                                                :max-scale="7"
+                                                :min-scale="0.2"
+                                                :preview-src-list="[scope.row.star.avatar_url]"
+                                                preview-teleported
+                                                z-index="999"
+                                                fit="cover"></el-image>
+                                            </div>
+                                            <div class="name">
+                                                <span>{{ scope.row.star.show_nickname }}</span>
+                                                <span class="dec">抖音号:{{ scope.row.star.unique_id }}</span>
+                                            </div>
+                                        </div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="粉丝数" width="200" prop="id">
+                                    <template #default="scope">
+                                        <div class="price">{{ scope.row.star.fans_count }}</div>
+                                        <div class="goods-price">
+                                            <span v-for="value in scope.row.star.fans_tag_list">{{ value }}</span></div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="本地粉丝数" width="120" prop="id">
+                                    <template #default="scope">
+                                        <div class="price">{{ scope.row.star.local_fans_count }}</div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="视频带货力" prop="category_id" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.star.talent_item_level_display">{{ scope.row.star.talent_item_level_display }}</span>
+                                        <span v-else>-</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="直播带货力" prop="talent_live_level_display" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.star.talent_live_level_display">{{ scope.row.star.talent_live_level_display }}</span>
+                                        <span v-else>-</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="内容力" prop="category_id" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.star.content_level_display">{{ scope.row.star.content_level_display }}</span>
+                                        <span v-else>-</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="信用分" prop="category_id" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.star.credit_score_display">{{ scope.row.star.credit_score_display }}</span>
+                                        <span v-else>-</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="视频榜" prop="category_id" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.star.rank_display">{{ scope.row.star.city_name }} 第{{ scope.row.star.rank_display }}名</span>
+                                        <span v-else>-</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="状态" prop="enable" width="120" align="center">
+                                    <template #default="scope">
+                                        <div class="status-success" v-if="scope.row.star.status==1"><sc-status-indicator type="success"></sc-status-indicator> 正常</div>
+                                        <div class="status-danger" v-if="scope.row.star.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 禁用</div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="操作" width="100" align="left" fixed="right">
+                                    <template #default="scope">
+                                        <el-button-group>
+                                            <el-button type="danger" v-if="scope.row.id=='0'" text size="small" @click="removeStar(scope.$index)">删除</el-button>
+                                            <el-button type="danger" v-else text size="small" :disabled="true">删除</el-button>
+                                        </el-button-group>
+                                    </template>
+                                </el-table-column>
+                            </scTable>
+                        </div>
+                    </el-form-item>
+                </el-form>
+            </el-main>
+            <el-footer>
+                <el-button @click="visible=false" size="large">取 消</el-button>
+                <el-button size="large" type="primary" :loading="isSaveing" @click="submitEdit()">保 存</el-button>
+            </el-footer>
+        </el-container>
+    </el-drawer>
+    <starMain ref="starMain" :multiple="true" @success="handleStar"></starMain>
+    <el-dialog title="一键设置佣金" v-model="quickData.visible" :width="460" append-to-body destroy-on-close :close-on-click-modal="false">
+        <el-form ref="quickForm" :model="quickData.formData" :rules="quickData.rules" label-width="100px" label-position="top">
+            <el-form-item label="输入后商品将设置相同佣金" prop="rate">
+                <el-input v-model="quickData.formData.rate" clearable placeholder="0%-29%">
+                    <template #suffix>%</template>
+                </el-input>
+                <div class="el-form-item-msg">佣金比例请设置在0%-29%之间</div>
+            </el-form-item>
+        </el-form>
+		<template #footer>
+            <el-button @click="quickData.visible=false" size="large">取 消</el-button>
+            <el-button size="large" type="primary" :loading="quickData.isSaveing" @click="submitRate()">保 存</el-button>
+		</template>
+    </el-dialog>
+</template>
+
+<script>
+import starMain from '@/views/merchant/components/star';
+export default {
+    components: {
+        starMain
+    },
+    data(){
+        return {
+            quickData:{
+                visible:false,
+                rate:null,
+                isSaveing:false,
+                formData:{
+                    rate:null
+                },
+                rules:{
+                    rate: [
+                        {required: true, message: '请输入'}
+                    ],
+                }
+            },
+            loading: false,
+            isSaveing: false,
+            mode:"add",
+            titleMap:{
+                goods:"修改计划商品佣金",
+                star:"达人管理"
+            },
+            visible:false,
+            formData:{
+                status:1
+            },
+            goodsData:[],
+            starData:[],
+        }
+    },
+    methods:{
+        quickGoods(){
+            this.quickData.visible = true;
+        },
+        open(mode = 'add'){
+            this.mode = mode;
+            this.visible = true;
+            return this
+        },
+        //表单注入数据
+        setData(data){
+            this.formData = JSON.parse(JSON.stringify(data));
+            this.goodsData = []
+            this.starData = []
+            this.getDetail()
+        },
+        async aloneSave(data){
+            var loading = this.$loading()
+            var resp = await this.$API.merPlan.goods.post({"id":this.formData.id,"commission_rate":data.commission_rate,"goods_id":data.goods.goods_id})
+            loading.close();
+            if (resp.code == 0) return this.$message.error(resp.msg);
+            this.$message.success(resp.msg);
+            this.getDetail()
+        },
+        async getDetail(){
+            this.loading = true;
+            var resp = await this.$API.merPlan.detail.get({"id":this.formData.id});
+            this.loading = false;
+            if (resp.code == 0) {
+                this.visible = false;
+                return this.$message.error(resp.msg);
+            }
+            var goodsData = resp.data.goods;
+            goodsData.forEach((item)=>{
+                item.rate_money = this.$TOOL.moneyFormat(parseFloat(item.commission_rate) * item.goods.price / 100);
+            })
+            this.goodsData = goodsData
+            this.starData = resp.data.star
+        },
+        setRate(index){
+            const goods = this.goodsData[index];
+            if (parseFloat(goods.commission_rate) > 29) {
+                this.goodsData[index].commission_rate = 0;
+                this.goodsData[index].rate_money = 0;
+                return ;
+            }
+            const rateMoney = this.$TOOL.moneyFormat(parseFloat(goods.commission_rate) * goods.goods.price / 100);
+            this.goodsData[index].rate_money = rateMoney;
+        },
+        addStar(){
+            this.$nextTick(() => {
+                this.$refs.starMain.open("add")
+            })
+        },
+        handleStar(data){
+            var newData = [];
+            data.forEach((value)=>{
+                const has = this.starData.some(item => item['unique_id'] === value['unique_id'])
+                if (!has) newData.push({"id":'0',"plan_id":this.formData.plan_id,"star":value,"unique_id":value.unique_id})
+            })
+            if (newData.length > 0) {
+                this.starData = this.starData.concat(newData);
+            }
+        },
+        removeStar(index){
+            console.log("index",index)
+            this.starData.splice(index,1);
+        },
+        async submitRate(){
+            var validate = await this.$refs.quickForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            if (parseFloat(this.quickData.formData.rate) > 29) {
+                this.quickData.formData.rate = 0;
+                return ;
+            }
+            this.quickData.isSaveing = true;
+            var goodsData = this.goodsData;
+            goodsData.forEach((item) =>{
+                const rateMoney = this.$TOOL.moneyFormat(parseFloat(this.quickData.formData.rate) * item.goods.price / 100);
+                item.rate_money = rateMoney;
+                item.commission_rate = this.quickData.formData.rate;
+            })
+            this.goodsData = goodsData;
+            this.quickData.isSaveing = false;
+            this.quickData.visible = false;
+        },
+        async submitEdit(){
+            const formData = {};
+            if (this.mode == 'star') {
+                formData.data = JSON.stringify(this.starData);
+            }
+            if (this.mode == 'goods') {
+                formData.data = JSON.stringify(this.goodsData);
+            }
+            formData.id = this.formData.id;
+            formData.type = this.mode
+            var loading = this.$loading()
+            this.isSaveing = true;
+            var resp = await this.$API.merPlan.goods.post(formData)
+            this.isSaveing = false;
+            loading.close();
+            if (resp.code == 0) return this.$message.error(resp.msg);
+            this.$message.success(resp.msg);
+            this.getDetail()
+        }
+    }
+}
+</script>
+
+<style>
+.goods-live{width: 100%;margin-top: 10px;}
+.flex-loading{display: flex;flex-direction: column;flex: 1;}
+</style>

+ 362 - 0
src/views/manage/cps/index/components/form.vue

@@ -0,0 +1,362 @@
+<template>
+    <el-drawer v-model="visible" title="在线客服" size="800px" destroy-on-close :close-on-click-modal="false" :with-header="false">
+        <el-container class="flex-column">
+            <div class="drawer-detail-main">
+                <div class="drawer-detail-header">
+                    <div class="drawer-detail-header-body">
+                        <div class="drawer-detail-header-left">{{titleMap[mode]}}</div>
+                        <div class="drawer-detail-header-left">
+                            <el-button type="default" icon="el-icon-close" @click="visible=false"></el-button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <el-main>
+                <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
+                    <el-form-item label="计划名称" prop="plan_name">
+                        <el-input v-model="formData.plan_name" clearable placeholder="请输入"></el-input>
+                        <div class="el-form-item-msg"></div>
+                    </el-form-item>
+                    <el-form-item label="联系电话" prop="merchant_phone">
+                        <el-input v-model="formData.merchant_phone" clearable placeholder="请输入"></el-input>
+                        <div class="el-form-item-msg">必须是真实可用的手机号码,否则计划可能会不通过审核</div>
+                    </el-form-item>
+                    <el-form-item label="推广团购商品">
+                        <el-button type="default" @click="addGoods" v-if="goodsData.length<50">添加团购商品({{ goodsData.length }}/50</el-button>
+                        <el-button type="default" @click="quickGoods" v-if="goodsData.length > 0">一键设置佣金</el-button>
+                        <div class="goods-live" v-if="goodsData.length>0">
+                            <scTable ref="starTable" :data="goodsData" row-key="id" height="300" hidePagination hideDo style="width: 750px;">
+                                <el-table-column label="商品信息" width="340" prop="name" fixed="left">
+                                    <template #default="scope">
+                                        <div class="goods-img">
+                                            <div class="img">
+                                                <el-image 
+                                                style="width: 54px; height: 54px"
+                                                :src="scope.row.image_list[0].url"
+                                                :zoom-rate="1.2"
+                                                :max-scale="7"
+                                                :min-scale="0.2"
+                                                :preview-src-list="[scope.row.image_list[0].url]"
+                                                preview-teleported
+                                                z-index="999"
+                                                fit="cover"></el-image>
+                                            </div>
+                                            <div class="name">
+                                                <span>{{ scope.row.product_name }}</span>
+                                                <span class="dec">商品编码:{{ scope.row.product_id }}</span>
+                                            </div>
+                                        </div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="佣金比例" prop="types" width="150">
+                                    <template #default="scope">
+                                        <el-input v-model="scope.row.rate" @input="setRate(scope.$index)" @focus="setRate(scope.$index)" placeholder="0%-29%">
+                                            <template #suffix>%</template>
+                                        </el-input>
+                                        <div class="el-form-item-msg">预估每单佣金 {{ scope.row.rate_money }}</div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="商品类型" prop="types" width="100"></el-table-column>
+                                <el-table-column label="价格" width="200" prop="id">
+                                    <template #default="scope">
+                                        <div class="price">{{ $TOOL.moneyFormat(scope.row.price) }}</div>
+                                        <div class="goods-price">
+                                            <div class="del">{{ $TOOL.moneyFormat(scope.row.line_price) }}</div>
+                                            <span>{{ $TOOL.disFormat(scope.row.price,scope.row.line_price) }}折</span></div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="剩余库存" prop="category_id" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.limit_use_rule==1">{{ scope.row.use_num_per_consume }}</span>
+                                        <span v-else>不限</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="状态" prop="enable" width="120" align="center">
+                                    <template #default="scope">
+                                        <div class="status-success" v-if="scope.row.status==1"><sc-status-indicator type="success"></sc-status-indicator> 正常</div>
+                                        <div class="status-danger" v-if="scope.row.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 禁用</div>
+                                        <div class="status-danger" v-if="scope.row.status==0"><sc-status-indicator type="danger"></sc-status-indicator> 审核中</div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="操作" width="100" align="left" fixed="right">
+                                    <template #default="scope">
+                                        <el-button-group>
+                                            <el-button type="danger" text size="small" @click="removeGoods(scope.$index)">删除</el-button>
+                                        </el-button-group>
+                                    </template>
+                                </el-table-column>
+                            </scTable>
+                        </div>
+                    </el-form-item>
+                    <el-form-item label="指定带货达人">
+                        <el-button type="default" @click="addStar" v-if="starData.length<200">添加达人({{ starData.length }}/200)</el-button>
+                        <div class="goods-live" v-if="starData.length>0">
+                            <scTable ref="starTable" :data="starData" row-key="id" height="300" hidePagination hideDo style="width: 750px;">
+                                <el-table-column label="达人" width="340" prop="name" fixed="left">
+                                    <template #default="scope">
+                                        <div class="goods-img">
+                                            <div class="img">
+                                                <el-image 
+                                                style="width: 54px; height: 54px"
+                                                :src="scope.row.avatar_url"
+                                                :zoom-rate="1.2"
+                                                :max-scale="7"
+                                                :min-scale="0.2"
+                                                :preview-src-list="[scope.row.avatar_url]"
+                                                preview-teleported
+                                                z-index="999"
+                                                fit="cover"></el-image>
+                                            </div>
+                                            <div class="name">
+                                                <span>{{ scope.row.show_nickname }}</span>
+                                                <span class="dec">抖音号:{{ scope.row.unique_id }}</span>
+                                            </div>
+                                        </div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="粉丝数" width="200" prop="id">
+                                    <template #default="scope">
+                                        <div class="price">{{ scope.row.fans_count }}</div>
+                                        <div class="goods-price">
+                                            <span v-for="value in scope.row.fans_tag_list">{{ value }}</span></div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="本地粉丝数" width="120" prop="id">
+                                    <template #default="scope">
+                                        <div class="price">{{ scope.row.local_fans_count }}</div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="视频带货力" prop="category_id" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.talent_item_level_display">{{ scope.row.talent_item_level_display }}</span>
+                                        <span v-else>-</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="直播带货力" prop="talent_live_level_display" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.talent_live_level_display">{{ scope.row.talent_live_level_display }}</span>
+                                        <span v-else>-</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="内容力" prop="category_id" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.content_level_display">{{ scope.row.content_level_display }}</span>
+                                        <span v-else>-</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="信用分" prop="category_id" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.credit_score_display">{{ scope.row.credit_score_display }}</span>
+                                        <span v-else>-</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="视频榜" prop="category_id" width="120">
+                                    <template #default="scope">
+                                        <span v-if="scope.row.rank_display">{{ scope.row.city_name }} 第{{ scope.row.rank_display }}名</span>
+                                        <span v-else>-</span>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="状态" prop="enable" width="120" align="center">
+                                    <template #default="scope">
+                                        <div class="status-success" v-if="scope.row.status==1"><sc-status-indicator type="success"></sc-status-indicator> 正常</div>
+                                        <div class="status-danger" v-if="scope.row.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 禁用</div>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column label="创建时间" prop="create_at" width="180"></el-table-column>
+                                <el-table-column label="操作" width="100" align="left" fixed="right">
+                                    <template #default="scope">
+                                        <el-button-group>
+                                            <el-button type="danger" text size="small" @click="removeStar(scope.$index)">删除</el-button>
+                                        </el-button-group>
+                                    </template>
+                                </el-table-column>
+                            </scTable>
+                        </div>
+                    </el-form-item>
+                    <!-- <el-form-item label="状态" prop="status">
+                        <el-radio-group v-model="formData.status">
+                            <el-radio-button :label="1">正常</el-radio-button>
+                            <el-radio-button :label="2">禁用</el-radio-button>
+                        </el-radio-group>
+                        <div class="el-form-item-msg">禁用后的达人不可绑定直播计划</div>
+                    </el-form-item> -->
+                </el-form>
+            </el-main>
+            <el-footer>
+                <el-button @click="visible=false" size="large">取 消</el-button>
+                <el-button v-if="mode!='show'" size="large" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
+            </el-footer>
+        </el-container>
+    </el-drawer>
+    <starMain ref="starMain" :multiple="true" @success="handleStar"></starMain>
+    <goodsMain ref="goodsMain" :multiple="true" @success="handleGoods"></goodsMain>
+    <el-dialog title="一键设置佣金" v-model="quickData.visible" :width="460" append-to-body destroy-on-close :close-on-click-modal="false">
+        <el-form ref="quickForm" :model="quickData.formData" :rules="quickData.rules" label-width="100px" label-position="top">
+            <el-form-item label="输入后商品将设置相同佣金" prop="rate">
+                <el-input v-model="quickData.formData.rate" clearable placeholder="0%-29%">
+                    <template #suffix>%</template>
+                </el-input>
+                <div class="el-form-item-msg">佣金比例请设置在0%-29%之间</div>
+            </el-form-item>
+        </el-form>
+		<template #footer>
+            <el-button @click="quickData.visible=false" size="large">取 消</el-button>
+            <el-button size="large" type="primary" :loading="quickData.isSaveing" @click="submitRate()">保 存</el-button>
+		</template>
+    </el-dialog>
+</template>
+
+<script>
+import starMain from '@/views/merchant/components/star';
+import goodsMain from '@/views/merchant/components/goods';
+export default {
+    components: {
+        starMain,goodsMain
+    },
+    data(){
+        return {
+            quickData:{
+                visible:false,
+                rate:null,
+                isSaveing:false,
+                formData:{
+                    rate:null
+                },
+                rules:{
+                    rate: [
+                        {required: true, message: '请输入'}
+                    ],
+                }
+            },
+            goodsData:[],
+            starData:[],
+            loading: false,
+            isSaveing: false,
+            mode:"add",
+            titleMap:{
+                add:"创建直播计划",
+                edit:"编辑直播计划"
+            },
+            visible:false,
+            formData:{
+                status:1
+            },
+            rules:{
+                status: [
+                    {required: true, message: '请选择'}
+                ],
+                plan_name: [
+                    {required: true, message: '请输入'}
+                ],
+                merchant_phone: [
+                    {required: true, message: '请输入'}
+                ]
+            }
+        }
+    },
+    methods:{
+        open(mode = 'add'){
+            this.mode = mode;
+            this.visible = true;
+            return this
+        },
+        //表单注入数据
+        setData(data){
+            this.formData = JSON.parse(JSON.stringify(data));
+        },
+        setRate(index){
+            const goods = this.goodsData[index];
+            if (parseFloat(goods.rate) > 29) {
+                this.goodsData[index].rate = 0;
+                this.goodsData[index].rate_money = 0;
+                return ;
+            }
+            const rateMoney = this.$TOOL.moneyFormat(parseFloat(goods.rate) * goods.price / 100);
+            this.goodsData[index].rate_money = rateMoney;
+        },
+        quickGoods(){
+            this.quickData.visible = true;
+        },
+        addGoods(){
+            this.$nextTick(() => {
+                this.$refs.goodsMain.open("add")
+            })
+        },
+        removeGoods(index){
+            this.goodsData.splice(index,1);
+        },
+        addStar(){
+            this.$nextTick(() => {
+                this.$refs.starMain.open("add")
+            })
+        },
+        removeStar(index){
+            this.starData.splice(index,1);
+        },
+        handleStar(data){
+            var newData = [];
+            data.forEach((value)=>{
+                const has = this.starData.some(item => item['id'] === value['id'])
+                if (!has) newData.push(value)
+            })
+            if (newData.length > 0) {
+                this.starData = this.starData.concat(newData);
+            }
+        },
+        handleGoods(data){
+            var newData = [];
+            data.forEach((value)=>{
+                value.rate = 0;
+                value.rate_money = 0;
+                const has = this.goodsData.some(item => item['id'] === value['id'])
+                if (!has) newData.push(value)
+            })
+            if (newData.length > 0) {
+                this.goodsData = this.goodsData.concat(newData);
+            }
+        },
+        async submitRate(){
+            var validate = await this.$refs.quickForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            if (parseFloat(this.quickData.formData.rate) > 29) {
+                this.quickData.formData.rate = 0;
+                return ;
+            }
+            this.quickData.isSaveing = true;
+            var goodsData = this.goodsData;
+            goodsData.forEach((item) =>{
+                const rateMoney = this.$TOOL.moneyFormat(parseFloat(this.quickData.formData.rate) * item.price / 100);
+                item.rate_money = rateMoney;
+                item.rate = this.quickData.formData.rate;
+            })
+            this.goodsData = goodsData;
+            this.quickData.isSaveing = false;
+            this.quickData.visible = false;
+        },
+        async submit(){
+            var validate = await this.$refs.dialogForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            if (this.goodsData.length == 0) return this.$message.error("请添加团购商品")
+            if (this.starData.length == 0) return this.$message.error("请添加达人")
+            this.isSaveing = true;
+            let submitData = JSON.parse(JSON.stringify(this.formData));
+            submitData.goods = JSON.stringify(this.goodsData);
+            submitData.star = JSON.stringify(this.starData);
+            var resp = await this.$API.merPlan.save.post(submitData);
+            this.isSaveing = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.visible = false;
+            this.formData = {};
+            this.$emit("success");
+        }
+    }
+}
+</script>
+
+<style>
+.text-center{text-align: center;}
+.goods-live{width: 100%;margin-top: 10px;}
+</style>

+ 75 - 0
src/views/manage/cps/index/components/option.vue

@@ -0,0 +1,75 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">按需操作</el-tag>
+        </legend>
+        <div class="op-header">
+            <div class="left-panel">
+                <el-button type="primary" icon="el-icon-plus" @click="table_add()">创建新计划</el-button>
+            </div>
+        </div>
+    </fieldset>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    props: {
+        dataSelect: { type: Array, default: () => [] },
+        dataSelectFull: { type: Array, default: () => [] }
+    },
+    data(){
+        return {
+
+        }
+    },
+    methods: {
+        table_add(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open("add")
+            })
+        },
+        table_sync(){
+            this.$confirm(`发起同步后,请耐心等待1-2分钟后再刷新当前数据列表`, '提示', {
+                type: 'warning'
+            }).then(async () => {
+                var resp = await this.$API.category.sync.get();
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(() => {
+
+            })
+        },
+        table_batch_status(status){
+            if (this.dataSelect.length == 0) {
+                return this.$message.error("请选择修改数据")
+            }
+            this.$confirm(`审核中的商品不支持该操作,请确认是否有勾选审核中的商品`, '提示', {
+                type: 'warning'
+            }).then(async () => {
+                var loading = this.$loading()
+                let submitData = {"id":this.dataSelect,"value":status,"field":"status","type":"batch"};
+                loading.close()
+                var resp = await this.$API.merGoods.batch.post(submitData);
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(() => {
+
+            })
+        },
+        handleSuccess(){
+            this.$emit("success");
+        }
+    }
+}
+</script>

+ 79 - 0
src/views/manage/cps/index/components/search.vue

@@ -0,0 +1,79 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">条件筛选</el-tag>
+        </legend>
+        <el-form class="lv-form-inline" ref="searchForm" :model="searchKey" label-position="right" label-width="100px">
+            <div class="search-form">
+                <div class="form-left">
+                    <el-row :gutter="10">
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="6">
+                            <el-input v-model="searchKey.poi_name" placeholder="请选择商家" clearbale readonly :style="{width:'100%'}" @click="selectStore">
+                                <template #append>
+                                    <el-tooltip effect="dark" content="点这里,清除选择" placement="top-start">
+                                        <div class="remove-a" @click="clearStore">清除</div>
+                                    </el-tooltip>
+                                </template>
+                                <template #prepend>所属商家</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-input v-model="searchKey.name" placeholder="达人昵称" clearable :style="{ width: '100%' }" @keyup.enter="searchForm()">
+                                <template #prepend>计划名称</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-select v-model="searchKey.status" clearable placeholder="请选择状态" @change="searchForm" :style="{width: '100%'}" class="diy-select">
+                                <el-option value="1" label="进行中"></el-option>
+                                <el-option value="2" label="已取消"></el-option>
+                                <template #prefix>状态</template>
+                            </el-select>
+                        </el-col>
+                        <el-col :xs="12" :sm="6" :md="6" :lg="6" :xl="4">
+                            <el-date-picker v-model="searchKey.create" :style="{width: '100%'}" placeholder="请选择创建时间" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" @change="searchForm" />
+                        </el-col>
+                    </el-row>
+                </div>
+                <div class="form-line"></div>
+                <div class="form-right">
+                    <el-button type="primary" icon="el-icon-search" @click="searchForm">搜索</el-button>
+                </div>
+            </div>
+        </el-form>
+    </fieldset>
+    <storeData ref="storeData" :multiple="false" @success="handleStore"></storeData>
+</template>
+
+<script>
+import storeData from '@/views/manage/components/agent';
+export default {
+    components: {
+        storeData
+    },
+    data(){
+        return {
+            searchKey:{}
+        }
+    },
+    methods: {
+        selectStore(){
+            this.$nextTick(()=>{
+                this.$refs.storeData.open()
+            })
+        },
+        handleStore(data){
+            this.searchKey.poi_id = data.poi_id;
+            this.searchKey.poi_name = data.poi_name;
+            this.$emit("success",this.searchKey);
+        },
+        clearStore(){
+            this.searchKey.poi_id = "";
+            this.searchKey.poi_name = "";
+            this.$emit("success",this.searchKey);
+        },
+        searchForm(){
+            this.$emit("success",this.searchKey);
+        }
+    }
+}
+</script>

+ 213 - 0
src/views/manage/cps/index/components/table.vue

@@ -0,0 +1,213 @@
+<template>
+    <scTable ref="table" :apiObj="list.apiObj" :params="searchKey" @selectionChange="selectionChange" row-key="id">
+        <el-table-column type="selection" width="50" fixed="left"></el-table-column>
+        <el-table-column label="计划名称" width="300" prop="id" fixed="left">
+            <template #default="scope">
+                <div class="price">{{ scope.row.plan_name }}</div>
+                <span class="dec">计划ID:{{ scope.row.plan_id }}</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="所属商家" prop="id" width="260">
+            <template #default="scope">
+                <div class="goods-img">
+                    <div class="name" v-if="scope.row.poi">
+                        <span>{{ scope.row.poi.poi_name }}</span>
+                        <span class="dec">{{ scope.row.poi.poi_address }}</span>
+                    </div>
+                    <div v-else>-</div>
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="抖音核销金额(元)" prop="id">
+            <template #header>
+                <el-tooltip effect="dark" placement="top-start" content="成交金额带来的核销金额">
+                    <div class="flex">抖音核销金额(元) <el-icon><el-icon-question-filled /></el-icon></div>
+                </el-tooltip>
+            </template>
+            <template #default="scope">
+                <span v-if="scope.row.done_money">{{ scope.row.done_money }}</span>
+                <span v-else>-</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="成交金额(元)" prop="category_id">
+            <template #header>
+                <el-tooltip effect="dark" placement="top-start">
+                    <template #content>除通过达人视频、直播直接下单的成交金额外,还包含消费者<br>看过达人视频后,通过抖音其他渠道下单的成交金额,例如搜索等。</template>
+                    <div class="flex">成交金额(元) <el-icon><el-icon-question-filled /></el-icon></div>
+                </el-tooltip>
+            </template>
+            <template #default="scope">
+                <span v-if="scope.row.order_money">{{ scope.row.order_money }}</span>
+                <span v-else>-</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="达人佣金(元)" prop="star_money">
+            <template #default="scope">
+                <span v-if="scope.row.star_money">{{ scope.row.star_money }}</span>
+                <span v-else>-</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="订单量" prop="category_id">
+            <template #default="scope">
+                <span v-if="scope.row.order_num">{{ scope.row.order_num }}</span>
+                <span v-else>-</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="状态" prop="enable" width="120" align="center">
+            <template #default="scope">
+                <div class="status-success" v-if="scope.row.status==1"><sc-status-indicator type="success"></sc-status-indicator> 进行中</div>
+                <div class="status-danger" v-if="scope.row.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 已取消</div>
+            </template>
+        </el-table-column>
+        <el-table-column label="创建时间" prop="create_at" width="180"></el-table-column>
+        <el-table-column label="操作" width="200" align="left" fixed="right">
+            <template #default="scope">
+                <el-button-group>
+                    <el-button size="small" text @click="table_rate(scope.row)" v-if="scope.row.status == 1">修改佣金</el-button>
+                    <el-button type="success" size="small" text @click="table_star(scope.row)" v-if="scope.row.status == 1">达人</el-button>
+                    <el-button type="danger" text size="small" @click="table_close(scope.row)" v-if="scope.row.status == 1">关闭</el-button>
+                    <el-button type="danger" text size="small" @click="table_del(scope.row)" v-if="scope.row.status == 2">删除</el-button>
+                </el-button-group>
+            </template>
+        </el-table-column>
+    </scTable>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+    <editMain ref="editForm" @success="handleSuccess"></editMain>
+</template>
+
+<script>
+import formMain from './form';
+import editMain from './edit';
+export default {
+    components: {
+        formMain,
+        editMain
+    },
+    data(){
+        return {
+            list: {
+                apiObj: this.$API.plan.list
+            },
+            dataSelect:[],
+            dataSelectFull:[],
+            searchKey:{}
+        }
+    },
+    
+    methods: {
+        table_rate(data){
+            this.$nextTick(() => {
+                this.$refs.editForm.open("goods").setData(data)
+            })
+        },
+        table_star(data){
+            this.$nextTick(() => {
+                this.$refs.editForm.open("star").setData(data)
+            })
+        },
+        table_auth(data){
+            this.$nextTick(() => {
+                this.$refs.comboMain.open("edit").setData(data)
+            })
+        },
+        table_update(data){
+            this.$confirm(`更新后可能数据没有变化,确定更新该达人的基础数据吗?`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var resp = await this.$API.merStar.update.post({"id":data.id});
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$refs.table.refresh()
+            }).catch(()=>{})
+        },
+        table_del(data){
+            this.$confirm(`删除后,所有该计划对应的数据将一并被删除`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var loading = this.$loading()
+                var resp = await this.$API.merPlan.merPlan.post({"id":data.id});
+                loading.close();
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$refs.table.refresh()
+            }).catch(()=>{})
+        },
+        table_close(data){
+            this.$confirm(`关闭该定向计划后,达人无法勾选对应商品进行直播`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var loading = this.$loading()
+                var resp = await this.$API.merPlan.close.post({"id":data.id});
+                loading.close();
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(()=>{})
+        },
+        refresh(){
+            this.$refs.table.refresh()
+        },
+        upData(data){
+            this.$refs.table.upData(data)
+        },
+        handleSuccess(){
+            this.$refs.table.refresh()
+        },
+        sortChange(event){
+            if (event.order) {
+                var data = {
+                    "field":event.prop,
+                    "order":event.order
+                }
+                this.$refs.table.upData(data)
+            } else {
+                this.$refs.table.reload(this.searchKey)
+            }
+            return ;
+        },
+        selectionChange(event){
+            this.dataSelect = [];
+            var arr = [];
+            var arrCompany = [];
+            event.forEach(function(val,index){
+                arr[index] = val.id;
+                arrCompany[index] = val;
+            });
+            this.dataSelectFull = arrCompany;
+            this.dataSelect = arr;
+            this.$emit("success",this.dataSelect);
+            this.$emit("successFull",this.dataSelectFull);
+        },
+        table_passwd(row){
+            this.$nextTick(() => {
+                this.$refs.userPasswd.open("edit").setData(row)
+            })
+        }
+    }
+}
+</script>
+
+<style>
+.goods-img{display: flex;gap: 5px;}
+.goods-img .name span{display: block;}
+.goods-img .name span.dec{color: #999;font-size: 12px;}
+.goods-price,.price{display: flex;align-items: center;gap: 5px;font-size: 14px;}
+.goods-price .del{text-decoration: line-through;}
+.goods-price span{background-color: #fff !important;
+    border: 1px solid #d3d9e0 !important;
+    border-radius: 4px;
+    box-sizing: border-box;
+    color: #6c737a !important;
+    display: inline-flex;
+    flex: none;
+    font-size: 12px;
+    line-height: 18px !important;
+    padding: 1px 6px !important;text-decoration: none;}
+.flex{display: flex;align-items: center;gap: 5px;}
+</style>

+ 47 - 0
src/views/manage/cps/index/index.vue

@@ -0,0 +1,47 @@
+<template>
+    <el-container class="flex-column">
+        <div class="table-search">
+            <search @success="handleSuccess"></search>
+            <optionBtn @success="handleSuccess" :dataSelect="dataSelect" :dataSelectFull="dataSelectFull" type="3"></optionBtn>
+        </div>
+        <el-main class="nopadding">
+            <div class="table-container">
+                <tablePage ref="tablePage" @success="tableHandle" @successFull="tableHandleFull" type="3"></tablePage>
+            </div>
+        </el-main>
+    </el-container>  
+</template>
+
+<script>
+import search from './components/search';
+import optionBtn from './components/option';
+import tablePage from './components/table';
+export default {
+    components: {
+        search,tablePage,optionBtn
+    },
+    data(){
+        return {
+            searchKey:{},
+            dataSelect:[],
+            dataSelectFull:[],
+        }
+    },
+    methods: {
+        tableHandle(data){
+            this.dataSelect = data;
+        },
+        tableHandleFull(data){
+            this.dataSelectFull = data;
+        },
+        handleSuccess(data){
+            this.$refs.tablePage.upData(data)
+        },
+        handleClick(name){
+            this.activeName = name;
+            this.searchKey.type = name;
+            this.$refs.tablePage.upData(this.searchKey)
+        }
+    }
+}
+</script>

+ 80 - 0
src/views/manage/cps/star/components/form.vue

@@ -0,0 +1,80 @@
+<template>
+    <el-dialog :title="titleMap[mode]" v-model="visible" :width="500" destroy-on-close @closed="$emit('closed')">
+        <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
+            <el-form-item label="达人抖音号" prop="name">
+                <el-input v-model="formData.name" clearable placeholder="请输入"></el-input>
+                <div class="el-form-item-msg">输入抖音号后,点击保存,系统自动获取达人基础信息</div>
+            </el-form-item>
+            <el-form-item label="状态" prop="status">
+                <el-radio-group v-model="formData.status">
+                    <el-radio-button :label="1">正常</el-radio-button>
+                    <el-radio-button :label="2">禁用</el-radio-button>
+                </el-radio-group>
+                <div class="el-form-item-msg">禁用后的达人不可绑定直播计划</div>
+            </el-form-item>
+        </el-form>
+		<template #footer>
+            <el-button @click="visible=false" size="large">取 消</el-button>
+            <el-button v-if="mode!='show'" size="large" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
+		</template>
+    </el-dialog>
+    
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            loading: false,
+            isSaveing: false,
+            mode:"add",
+            titleMap:{
+                add:"绑定达人",
+                edit:"绑定达人"
+            },
+            visible:false,
+            formData:{
+                status:1
+            },
+            rules:{
+                enable: [
+                    {required: true, message: '请选择'}
+                ],
+                name: [
+                    {required: true, message: '请输入'}
+                ]
+            }
+        }
+    },
+    methods:{
+        open(mode = 'add'){
+            this.mode = mode;
+            this.visible = true;
+            return this
+        },
+        //表单注入数据
+        setData(data){
+            this.formData = JSON.parse(JSON.stringify(data));
+        },
+        async submit(){
+            var validate = await this.$refs.dialogForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            this.isSaveing = true;
+            let submitData = JSON.parse(JSON.stringify(this.formData));
+            var resp = await this.$API.merStar.save.post(submitData);
+            this.isSaveing = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.visible = false;
+            this.formData = {status:1};
+            this.$emit("success");
+        }
+    }
+}
+</script>
+
+<style>
+.text-center{text-align: center;}
+</style>

+ 75 - 0
src/views/manage/cps/star/components/option.vue

@@ -0,0 +1,75 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">按需操作</el-tag>
+        </legend>
+        <div class="op-header">
+            <div class="left-panel">
+                <el-button type="primary" icon="el-icon-plus" @click="table_add()">绑定达人</el-button>
+            </div>
+        </div>
+    </fieldset>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    props: {
+        dataSelect: { type: Array, default: () => [] },
+        dataSelectFull: { type: Array, default: () => [] }
+    },
+    data(){
+        return {
+
+        }
+    },
+    methods: {
+        table_add(){
+            this.$nextTick(() => {
+                this.$refs.formMain.open("add")
+            })
+        },
+        table_sync(){
+            this.$confirm(`发起同步后,请耐心等待1-2分钟后再刷新当前数据列表`, '提示', {
+                type: 'warning'
+            }).then(async () => {
+                var resp = await this.$API.category.sync.get();
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(() => {
+
+            })
+        },
+        table_batch_status(status){
+            if (this.dataSelect.length == 0) {
+                return this.$message.error("请选择修改数据")
+            }
+            this.$confirm(`审核中的商品不支持该操作,请确认是否有勾选审核中的商品`, '提示', {
+                type: 'warning'
+            }).then(async () => {
+                var loading = this.$loading()
+                let submitData = {"id":this.dataSelect,"value":status,"field":"status","type":"batch"};
+                loading.close()
+                var resp = await this.$API.merGoods.batch.post(submitData);
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(() => {
+
+            })
+        },
+        handleSuccess(){
+            this.$emit("success");
+        }
+    }
+}
+</script>

+ 77 - 0
src/views/manage/cps/star/components/search.vue

@@ -0,0 +1,77 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">条件筛选</el-tag>
+        </legend>
+        <el-form class="lv-form-inline" ref="searchForm" :model="searchKey" label-position="right" label-width="100px">
+            <div class="search-form">
+                <div class="form-left">
+                    <el-row :gutter="10">
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="6">
+                            <el-input v-model="searchKey.poi_name" placeholder="请选择商家" clearbale readonly :style="{width:'100%'}" @click="selectStore">
+                                <template #append>
+                                    <el-tooltip effect="dark" content="点这里,清除选择" placement="top-start">
+                                        <div class="remove-a" @click="clearStore">清除</div>
+                                    </el-tooltip>
+                                </template>
+                                <template #prepend>所属商家</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-input v-model="searchKey.name" placeholder="达人昵称" clearable :style="{ width: '100%' }" @keyup.enter="searchForm()">
+                                <template #prepend>达人昵称</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-input v-model="searchKey.unique" placeholder="抖音号" clearable :style="{ width: '100%' }" @keyup.enter="searchForm()">
+                                <template #prepend>抖音号</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="6" :md="6" :lg="6" :xl="4">
+                            <el-date-picker v-model="searchKey.create" :style="{width: '100%'}" placeholder="请选择创建时间" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" @change="searchForm" />
+                        </el-col>
+                    </el-row>
+                </div>
+                <div class="form-line"></div>
+                <div class="form-right">
+                    <el-button type="primary" icon="el-icon-search" @click="searchForm">搜索</el-button>
+                </div>
+            </div>
+        </el-form>
+    </fieldset>
+    <storeData ref="storeData" :multiple="false" @success="handleStore"></storeData>
+</template>
+
+<script>
+import storeData from '@/views/manage/components/agent';
+export default {
+    components: {
+        storeData
+    },
+    data(){
+        return {
+            searchKey:{}
+        }
+    },
+    methods: {
+        selectStore(){
+            this.$nextTick(()=>{
+                this.$refs.storeData.open()
+            })
+        },
+        handleStore(data){
+            this.searchKey.poi_id = data.poi_id;
+            this.searchKey.poi_name = data.poi_name;
+            this.$emit("success",this.searchKey);
+        },
+        clearStore(){
+            this.searchKey.poi_id = "";
+            this.searchKey.poi_name = "";
+            this.$emit("success",this.searchKey);
+        },
+        searchForm(){
+            this.$emit("success",this.searchKey);
+        }
+    }
+}
+</script>

+ 218 - 0
src/views/manage/cps/star/components/table.vue

@@ -0,0 +1,218 @@
+<template>
+    <scTable ref="table" :apiObj="list.apiObj" :params="searchKey" @selectionChange="selectionChange" row-key="id">
+        <el-table-column type="selection" width="50" fixed="left"></el-table-column>
+        <el-table-column label="达人" width="340" prop="name" fixed="left">
+            <template #default="scope">
+                <div class="goods-img">
+                    <div class="img">
+                        <el-image 
+                        style="width: 54px; height: 54px"
+                        :src="scope.row.avatar_url"
+                        :zoom-rate="1.2"
+                        :max-scale="7"
+                        :min-scale="0.2"
+                        :preview-src-list="[scope.row.avatar_url]"
+                        preview-teleported
+                        z-index="999"
+                        fit="cover"></el-image>
+                    </div>
+                    <div class="name">
+                        <span>{{ scope.row.show_nickname }}</span>
+                        <span class="dec">抖音号:{{ scope.row.unique_id }}</span>
+                    </div>
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="所属商家" prop="id" width="260">
+            <template #default="scope">
+                <div class="goods-img">
+                    <div class="name" v-if="scope.row.poi">
+                        <span>{{ scope.row.poi.poi_name }}</span>
+                        <span class="dec">{{ scope.row.poi.poi_address }}</span>
+                    </div>
+                    <div v-else>-</div>
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="粉丝数" width="200" prop="id">
+            <template #default="scope">
+                <div class="price">{{ scope.row.fans_count }}</div>
+                <div class="goods-price">
+                    <span v-for="value in scope.row.fans_tag_list">{{ value }}</span></div>
+            </template>
+        </el-table-column>
+        <el-table-column label="本地粉丝数" width="120" prop="id">
+            <template #default="scope">
+                <div class="price">{{ scope.row.local_fans_count }}</div>
+            </template>
+        </el-table-column>
+        <el-table-column label="视频带货力" prop="category_id" width="120">
+            <template #default="scope">
+                <span v-if="scope.row.talent_item_level_display">{{ scope.row.talent_item_level_display }}</span>
+                <span v-else>-</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="直播带货力" prop="talent_live_level_display" width="120">
+            <template #default="scope">
+                <span v-if="scope.row.talent_live_level_display">{{ scope.row.talent_live_level_display }}</span>
+                <span v-else>-</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="内容力" prop="category_id" width="120">
+            <template #default="scope">
+                <span v-if="scope.row.content_level_display">{{ scope.row.content_level_display }}</span>
+                <span v-else>-</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="信用分" prop="category_id" width="120">
+            <template #default="scope">
+                <span v-if="scope.row.credit_score_display">{{ scope.row.credit_score_display }}</span>
+                <span v-else>-</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="视频榜" prop="category_id" width="120">
+            <template #default="scope">
+                <span>{{ scope.row.city_name }} {{ scope.row.rank_display?'第'+scope.row.rank_display+'名':'无名次' }}</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="状态" prop="enable" width="120" align="center">
+            <template #default="scope">
+                <div class="status-success" v-if="scope.row.status==1"><sc-status-indicator type="success"></sc-status-indicator> 正常</div>
+                <div class="status-danger" v-if="scope.row.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 禁用</div>
+            </template>
+        </el-table-column>
+        <el-table-column label="创建时间" prop="create_at" width="180"></el-table-column>
+        <el-table-column label="操作" width="180" align="left" fixed="right">
+            <template #default="scope">
+                <el-button-group>
+                    <el-button size="small" text @click="table_update(scope.row)" v-if="scope.row.status == 1">更新</el-button>
+                    <el-button type="danger" text size="small" @click="table_del(scope.row)">删除</el-button>
+                </el-button-group>
+            </template>
+        </el-table-column>
+    </scTable>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    data(){
+        return {
+            list: {
+                apiObj: this.$API.star.list
+            },
+            dataSelect:[],
+            dataSelectFull:[],
+            searchKey:{}
+        }
+    },
+    
+    methods: {
+        table_auth(data){
+            this.$nextTick(() => {
+                this.$refs.comboMain.open("edit").setData(data)
+            })
+        },
+        table_update(data){
+            this.$confirm(`更新后可能数据没有变化,确定更新该达人的基础数据吗?`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var resp = await this.$API.merStar.update.post({"id":data.id});
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$refs.table.refresh()
+            }).catch(()=>{})
+        },
+        table_life(data){
+            this.$confirm(`来客下架成功后,在小程序中将不展示该商品,同时也将无法二次上架`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var resp = await this.$API.merGoods.off.post({"id":data.id});
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(()=>{})
+        },
+        table_view(data){
+            this.$router.push({path:"/merchant/goods/edit",query:{"product_id":data.product_id,"id":data.id,"spm":(new Date()).getTime()}})
+        },
+        table_del(data){
+            this.$confirm(`删除店铺后,所有有关该店铺的门店、订单等信息都将删除,不可恢复,确定要执行删除吗`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var resp = await this.$API.shop.del.post({"id":data.id});
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(()=>{})
+        },
+        refresh(){
+            this.$refs.table.refresh()
+        },
+        upData(data){
+            this.$refs.table.upData(data)
+        },
+        handleSuccess(){
+            this.$refs.table.refresh()
+        },
+        sortChange(event){
+            if (event.order) {
+                var data = {
+                    "field":event.prop,
+                    "order":event.order
+                }
+                this.$refs.table.upData(data)
+            } else {
+                this.$refs.table.reload(this.searchKey)
+            }
+            return ;
+        },
+        selectionChange(event){
+            this.dataSelect = [];
+            var arr = [];
+            var arrCompany = [];
+            event.forEach(function(val,index){
+                arr[index] = val.id;
+                arrCompany[index] = val;
+            });
+            this.dataSelectFull = arrCompany;
+            this.dataSelect = arr;
+            this.$emit("success",this.dataSelect);
+            this.$emit("successFull",this.dataSelectFull);
+        },
+        table_passwd(row){
+            this.$nextTick(() => {
+                this.$refs.userPasswd.open("edit").setData(row)
+            })
+        }
+    }
+}
+</script>
+
+<style>
+.goods-img{display: flex;gap: 5px;}
+.goods-img .name span{display: block;}
+.goods-img .name span.dec{color: #999;font-size: 12px;}
+.goods-price,.price{display: flex;align-items: center;gap: 5px;font-size: 14px;}
+.goods-price .del{text-decoration: line-through;}
+.goods-price span{background-color: #fff !important;
+    border: 1px solid #d3d9e0 !important;
+    border-radius: 4px;
+    box-sizing: border-box;
+    color: #6c737a !important;
+    display: inline-flex;
+    flex: none;
+    font-size: 12px;
+    line-height: 18px !important;
+    padding: 1px 6px !important;text-decoration: none;}
+</style>

+ 47 - 0
src/views/manage/cps/star/index.vue

@@ -0,0 +1,47 @@
+<template>
+    <el-container class="flex-column">
+        <div class="table-search">
+            <search @success="handleSuccess"></search>
+            <optionBtn @success="handleSuccess" :dataSelect="dataSelect" :dataSelectFull="dataSelectFull" type="3"></optionBtn>
+        </div>
+        <el-main class="nopadding">
+            <div class="table-container">
+                <tablePage ref="tablePage" @success="tableHandle" @successFull="tableHandleFull" type="3"></tablePage>
+            </div>
+        </el-main>
+    </el-container>  
+</template>
+
+<script>
+import search from './components/search';
+import optionBtn from './components/option';
+import tablePage from './components/table';
+export default {
+    components: {
+        search,tablePage,optionBtn
+    },
+    data(){
+        return {
+            searchKey:{},
+            dataSelect:[],
+            dataSelectFull:[],
+        }
+    },
+    methods: {
+        tableHandle(data){
+            this.dataSelect = data;
+        },
+        tableHandleFull(data){
+            this.dataSelectFull = data;
+        },
+        handleSuccess(data){
+            this.$refs.tablePage.upData(data)
+        },
+        handleClick(name){
+            this.activeName = name;
+            this.searchKey.type = name;
+            this.$refs.tablePage.upData(this.searchKey)
+        }
+    }
+}
+</script>

+ 13 - 0
src/views/manage/finance/open/index.vue

@@ -0,0 +1,13 @@
+<template>
+
+</template>
+
+<script>
+export default{
+    data() {
+        return {
+            
+        }
+    }
+}
+</script>

+ 85 - 0
src/views/manage/goods/index/components/form.vue

@@ -0,0 +1,85 @@
+<template>
+    <el-dialog :title="titleMap[mode]" v-model="visible" :width="500" destroy-on-close @closed="$emit('closed')">
+        <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
+            <el-form-item label="品类名称" prop="name">
+                <el-input v-model="formData.name" clearable placeholder="请输入"></el-input>
+                <div class="el-form-item-msg"></div>
+            </el-form-item>
+            <el-form-item label="状态" prop="enable">
+                <el-radio-group v-model="formData.enable">
+                    <el-radio-button :label="1">正常</el-radio-button>
+                    <el-radio-button :label="2">禁用</el-radio-button>
+                </el-radio-group>
+            </el-form-item>
+        </el-form>
+		<template #footer>
+            <el-button @click="visible=false" size="large">取 消</el-button>
+            <el-button v-if="mode!='show'" size="large" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
+		</template>
+    </el-dialog>
+    
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            loading: false,
+            isSaveing: false,
+            mode:"add",
+            titleMap:{
+                add:"新增店铺",
+                edit:"编辑品类信息"
+            },
+            visible:false,
+            formData:{},
+            rules:{
+                enable: [
+                    {required: true, message: '请选择'}
+                ],
+                name: [
+                    {required: true, message: '请输入'}
+                ]
+            }
+        }
+    },
+    methods:{
+        open(mode = 'add'){
+            this.mode = mode;
+            this.visible = true;
+            return this
+        },
+        //表单注入数据
+        setData(data){
+            this.formData = JSON.parse(JSON.stringify(data));
+        },
+        async submit(){
+            var validate = await this.$refs.dialogForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            this.isSaveing = true;
+            let submitData = JSON.parse(JSON.stringify(this.formData));
+            if (this.formData.vip_end) {
+                submitData.vip_end = this.$TOOL.dateFormat(this.formData.vip_end, "yyyy-MM-dd");
+            }
+            if (this.mode == 'add') {
+                var resp = await this.$API.catogory.save.post(submitData);
+            } else {
+                var resp = await this.$API.catogory.edit.post(submitData);
+            }
+            this.isSaveing = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg);
+            }
+            this.$message.success(resp.msg);
+            this.visible = false;
+            this.formData = {};
+            this.submitState = false;
+            this.$emit("success");
+        }
+    }
+}
+</script>
+
+<style>
+.text-center{text-align: center;}
+</style>

+ 75 - 0
src/views/manage/goods/index/components/option.vue

@@ -0,0 +1,75 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">按需操作</el-tag>
+        </legend>
+        <div class="op-header">
+            <div class="left-panel">
+                <el-button type="primary" icon="el-icon-plus" @click="table_add()">创建商品</el-button>
+                <!-- <el-button icon="el-icon-unlock" @click="table_batch_status(1)" :disabled="dataSelect.length>0?false:true">上架</el-button>
+                <el-button icon="el-icon-lock" type="danger" @click="table_batch_status(2)" :disabled="dataSelect.length>0?false:true">下架</el-button> -->
+            </div>
+        </div>
+    </fieldset>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    props: {
+        dataSelect: { type: Array, default: () => [] },
+        dataSelectFull: { type: Array, default: () => [] }
+    },
+    data(){
+        return {
+
+        }
+    },
+    methods: {
+        table_add(){
+            this.$router.push('/manage/goods/op/add')
+        },
+        table_sync(){
+            this.$confirm(`发起同步后,请耐心等待1-2分钟后再刷新当前数据列表`, '提示', {
+                type: 'warning'
+            }).then(async () => {
+                var resp = await this.$API.category.sync.get();
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(() => {
+
+            })
+        },
+        table_batch_status(status){
+            if (this.dataSelect.length == 0) {
+                return this.$message.error("请选择修改数据")
+            }
+            this.$confirm(`审核中的商品不支持该操作,请确认是否有勾选审核中的商品`, '提示', {
+                type: 'warning'
+            }).then(async () => {
+                var loading = this.$loading()
+                let submitData = {"id":this.dataSelect,"value":status,"field":"status","type":"batch"};
+                loading.close()
+                var resp = await this.$API.merGoods.batch.post(submitData);
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(() => {
+
+            })
+        },
+        handleSuccess(){
+            this.$emit("success");
+        }
+    }
+}
+</script>

+ 81 - 0
src/views/manage/goods/index/components/search.vue

@@ -0,0 +1,81 @@
+<template>
+    <fieldset>
+        <legend>
+            <el-tag type="info">条件筛选</el-tag>
+        </legend>
+        <el-form class="lv-form-inline" ref="searchForm" :model="searchKey" label-position="right" label-width="100px">
+            <div class="search-form">
+                <div class="form-left">
+                    <el-row :gutter="10">
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="6">
+                            <el-input v-model="searchKey.poi_name" placeholder="请选择商家" clearbale readonly :style="{width:'100%'}" @click="selectStore">
+                                <template #append>
+                                    <el-tooltip effect="dark" content="点这里,清除选择" placement="top-start">
+                                        <div class="remove-a" @click="clearStore">清除</div>
+                                    </el-tooltip>
+                                </template>
+                                <template #prepend>所属商家</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-input v-model="searchKey.title" placeholder="商品标题" clearable :style="{ width: '100%' }" @keyup.enter="searchForm()">
+                                <template #prepend>商品标题</template>
+                            </el-input>
+                        </el-col>
+                        <el-col :xs="12" :sm="12" :md="12" :lg="6" :xl="4">
+                            <el-select v-model="searchKey.status" clearable placeholder="请选择状态" @change="searchForm" :style="{width: '100%'}" class="diy-select">
+                                <el-option value="1" label="审核中"></el-option>
+                                <el-option value="2" label="售卖中"></el-option>
+                                <el-option value="3" label="已下架"></el-option>
+                                <el-option value="4" label="已删除"></el-option>
+                                <template #prefix>状态</template>
+                            </el-select>
+                        </el-col>
+                        <el-col :xs="12" :sm="6" :md="6" :lg="6" :xl="4">
+                            <el-date-picker v-model="searchKey.create" :style="{width: '100%'}" placeholder="请选择创建时间" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" @change="searchForm" />
+                        </el-col>
+                    </el-row>
+                </div>
+                <div class="form-line"></div>
+                <div class="form-right">
+                    <el-button type="primary" icon="el-icon-search" @click="searchForm">搜索</el-button>
+                </div>
+            </div>
+        </el-form>
+    </fieldset>
+    <storeData ref="storeData" :multiple="false" @success="handleStore"></storeData>
+</template>
+
+<script>
+import storeData from '@/views/manage/components/agent';
+export default {
+    components: {
+        storeData
+    },
+    data(){
+        return {
+            searchKey:{}
+        }
+    },
+    methods: {
+        selectStore(){
+            this.$nextTick(()=>{
+                this.$refs.storeData.open()
+            })
+        },
+        handleStore(data){
+            this.searchKey.poi_id = data.poi_id;
+            this.searchKey.poi_name = data.poi_name;
+            this.$emit("success",this.searchKey);
+        },
+        clearStore(){
+            this.searchKey.poi_id = "";
+            this.searchKey.poi_name = "";
+            this.$emit("success",this.searchKey);
+        },
+        searchForm(){
+            this.$emit("success",this.searchKey);
+        }
+    }
+}
+</script>

+ 200 - 0
src/views/manage/goods/index/components/table.vue

@@ -0,0 +1,200 @@
+<template>
+    <scTable ref="table" :apiObj="list.apiObj" :params="searchKey" @selectionChange="selectionChange" row-key="id">
+        <el-table-column type="selection" width="50" fixed="left"></el-table-column>
+        <el-table-column label="商品ID" width="180" fixed="left" prop="goods_id">
+            <template #default="scope">
+                {{ scope.row.goods_id?scope.row.goods_id:'审核中' }}
+            </template>
+        </el-table-column>
+        <el-table-column label="所属商家" prop="id" width="260">
+            <template #default="scope">
+                <div class="goods-img">
+                    <div class="name" v-if="scope.row.poi">
+                        <span>{{ scope.row.poi.poi_name }}</span>
+                        <span class="dec">{{ scope.row.poi.poi_address }}</span>
+                    </div>
+                    <div v-else>-</div>
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="商品类型" prop="types" width="100"></el-table-column>
+        <el-table-column label="商品信息" width="340" prop="name">
+            <template #default="scope">
+                <div class="goods-img">
+                    <div class="img">
+                        <el-image 
+                        style="width: 54px; height: 54px"
+                        :src="scope.row.image_list[0].url"
+                        :zoom-rate="1.2"
+                        :max-scale="7"
+                        :min-scale="0.2"
+                        :preview-src-list="[scope.row.image_list[0].url]"
+                        preview-teleported
+                        z-index="999"
+                        fit="cover"></el-image>
+                    </div>
+                    <div class="name">
+                        <span>{{ scope.row.product_name }}</span>
+                        <span class="dec">商品编码:{{ scope.row.product_id }}</span>
+                    </div>
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="价格" width="200" prop="id">
+            <template #default="scope">
+                <div class="price">{{ $TOOL.moneyFormat(scope.row.price) }}</div>
+                <div class="goods-price">
+                    <div class="del">{{ $TOOL.moneyFormat(scope.row.line_price) }}</div>
+                    <span>{{ $TOOL.disFormat(scope.row.price,scope.row.line_price) }}折</span></div>
+            </template>
+        </el-table-column>
+        <el-table-column label="剩余库存" prop="category_id" width="120">
+            <template #default="scope">
+                <span v-if="scope.row.limit_use_rule==1">{{ scope.row.use_num_per_consume }}</span>
+                <span v-else>不限</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="状态" prop="enable" width="120" align="center">
+            <template #default="scope">
+                <div class="status-success" v-if="scope.row.status==1"><sc-status-indicator type="success"></sc-status-indicator> 售卖中</div>
+                <div class="status-danger" v-if="scope.row.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 已下架</div>
+                <div class="status-info" v-if="scope.row.status==3"><sc-status-indicator type="danger"></sc-status-indicator> 已删除</div>
+                <div class="status-danger" v-if="scope.row.status==0"><sc-status-indicator type="danger"></sc-status-indicator> 审核中</div>
+                <div v-if="scope.row.status==4">
+                    <el-popover :width="300" trigger="hover" placement="top-start" title="驳回原因">
+                        <template #reference>
+                            <div class="status-danger" v-if="scope.row.status==4"><sc-status-indicator type="danger"></sc-status-indicator> 审核驳回 <el-icon><el-icon-question-filled /></el-icon></div>
+                        </template>
+                        <div v-html="scope.row.reason"></div>
+                    </el-popover>
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="创建时间" prop="create_at" width="180"></el-table-column>
+        <el-table-column label="操作" width="180" align="left" fixed="right">
+            <template #default="scope">
+                <el-button-group>
+                    <el-button size="small" type="warning" text @click="table_life(scope.row)" v-if="scope.row.status == 1">下架</el-button>
+                    <el-button size="small" type="warning" text @click="table_life(scope.row)" v-if="scope.row.status == 2">上架</el-button>
+                </el-button-group>
+                <el-button-group>
+                    <el-button size="small" text @click="table_view(scope.row)" v-if="scope.row.status == 1 || scope.row.status == 4">编辑</el-button>
+                    <el-button type="danger" text size="small" @click="table_del(scope.row)" v-if="scope.row.status == 2 || scope.row.status == 4">删除</el-button>
+                    <el-button type="danger" text size="small" v-if="scope.row.status == 0">-</el-button>
+                </el-button-group>
+            </template>
+        </el-table-column>
+    </scTable>
+    <formMain ref="formMain" @success="handleSuccess"></formMain>
+</template>
+
+<script>
+import formMain from './form';
+export default {
+    components: {
+        formMain
+    },
+    data(){
+        return {
+            list: {
+                apiObj: this.$API.goods.list
+            },
+            dataSelect:[],
+            dataSelectFull:[],
+            searchKey:{}
+        }
+    },
+    
+    methods: {
+        table_auth(data){
+            this.$nextTick(() => {
+                this.$refs.comboMain.open("edit").setData(data)
+            })
+        },
+        table_life(data){
+            this.$confirm(`来客下架成功后,在小程序中将不展示该商品,同时也将无法二次上架`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var resp = await this.$API.merGoods.off.post({"id":data.id});
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(()=>{})
+        },
+        table_view(data){
+            this.$router.push({path:"/manage/goods/op/edit",query:{"product_id":data.product_id,"id":data.id,"spm":(new Date()).getTime()}})
+        },
+        table_del(data){
+            this.$confirm(`删除店铺后,所有有关该店铺的门店、订单等信息都将删除,不可恢复,确定要执行删除吗`, '提示', {
+                type: 'warning'
+            }).then(async ()=>{
+                var resp = await this.$API.shop.del.post({"id":data.id});
+                if (resp.code == 0) {
+                    return this.$message.error(resp.msg);
+                }
+                this.$message.success(resp.msg);
+                this.$emit("success");
+            }).catch(()=>{})
+        },
+        refresh(){
+            this.$refs.table.refresh()
+        },
+        upData(data){
+            this.$refs.table.upData(data)
+        },
+        handleSuccess(){
+            this.$refs.table.refresh()
+        },
+        sortChange(event){
+            if (event.order) {
+                var data = {
+                    "field":event.prop,
+                    "order":event.order
+                }
+                this.$refs.table.upData(data)
+            } else {
+                this.$refs.table.reload(this.searchKey)
+            }
+            return ;
+        },
+        selectionChange(event){
+            this.dataSelect = [];
+            var arr = [];
+            var arrCompany = [];
+            event.forEach(function(val,index){
+                arr[index] = val.id;
+                arrCompany[index] = val;
+            });
+            this.dataSelectFull = arrCompany;
+            this.dataSelect = arr;
+            this.$emit("success",this.dataSelect);
+            this.$emit("successFull",this.dataSelectFull);
+        },
+        table_passwd(row){
+            this.$nextTick(() => {
+                this.$refs.userPasswd.open("edit").setData(row)
+            })
+        }
+    }
+}
+</script>
+
+<style>
+.goods-img{display: flex;gap: 5px;}
+.goods-img .name span{display: block;}
+.goods-img .name span.dec{color: #999;font-size: 12px;}
+.goods-price,.price{display: flex;align-items: center;gap: 5px;font-size: 14px;}
+.goods-price .del{text-decoration: line-through;}
+.goods-price span{background-color: #fff !important;
+    border: 1px solid #d3d9e0 !important;
+    border-radius: 4px;
+    box-sizing: border-box;
+    color: #6c737a !important;
+    display: inline-flex;
+    flex: none;
+    font-size: 12px;
+    line-height: 18px !important;
+    padding: 1px 6px !important;text-decoration: none;}
+</style>

+ 45 - 1
src/views/manage/goods/index/index.vue

@@ -1,3 +1,47 @@
 <template>
 <template>
+    <el-container class="flex-column">
+        <div class="table-search">
+            <search @success="handleSuccess"></search>
+            <optionBtn @success="handleSuccess" :dataSelect="dataSelect" :dataSelectFull="dataSelectFull" type="3"></optionBtn>
+        </div>
+        <el-main class="nopadding">
+            <div class="table-container">
+                <tablePage ref="tablePage" @success="tableHandle" @successFull="tableHandleFull" type="3"></tablePage>
+            </div>
+        </el-main>
+    </el-container>  
+</template>
 
 
-</template>
+<script>
+import search from './components/search';
+import optionBtn from './components/option';
+import tablePage from './components/table';
+export default {
+    components: {
+        search,tablePage,optionBtn
+    },
+    data(){
+        return {
+            searchKey:{},
+            dataSelect:[],
+            dataSelectFull:[],
+        }
+    },
+    methods: {
+        tableHandle(data){
+            this.dataSelect = data;
+        },
+        tableHandleFull(data){
+            this.dataSelectFull = data;
+        },
+        handleSuccess(data){
+            this.$refs.tablePage.upData(data)
+        },
+        handleClick(name){
+            this.activeName = name;
+            this.searchKey.type = name;
+            this.$refs.tablePage.upData(this.searchKey)
+        }
+    }
+}
+</script>

+ 881 - 0
src/views/manage/goods/op/add.vue

@@ -0,0 +1,881 @@
+<template>
+    <el-container>
+        <el-main>
+            <el-row :gutter="20">
+                <el-col :span="18">
+                    <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="140px" label-position="right">
+                        <el-card shadow="never" header="商品类型" v-loading="channelLoad">
+                            <el-form-item label="商品品类" prop="category">
+                                <el-cascader ref="cascaderRef" v-model="formData.category" :options="categoryData" :props="deptsProps" @change="getTemplate" clearable style="width: 50%;" />
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-form-item label="商品类型" prop="product_type" v-if="typeData">
+                                <el-radio-group v-model="formData.product_type">
+                                    <el-radio border :label="item.key" v-for="(item,index) in typeData" :key="index">{{item.name}}</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                        </el-card>
+                        <template v-if="showNext">
+                        <!-- <el-card shadow="never" header="商家信息">
+                            <el-form-item label="收款方式" prop="settle_type">
+                                <el-radio-group v-model="formData.settle_type">
+                                    <el-radio border :label="1">总店结算</el-radio>
+                                    <el-radio border :label="2">分店结算</el-radio>
+                                    <el-radio border :label="3">区域结算</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg">
+                                    <span v-if="formData.settle_type==1">现有支付账户统一接收该团购产生的所有账款 </span>
+                                    <span v-if="formData.settle_type==2">若分店在消费者核销时未开通收款账户或未授权管理门店,则分店款项对应结算给公司账户或被授权的公司账户  </span>
+                                    <span v-if="formData.settle_type==3">区域账户统一接收关联门店产生的所有账款,如分店未关联区域收款账户,该分店的款项自动结算给总店账户  </span>
+                                </div>
+                            </el-form-item>
+                        </el-card> -->
+                        <el-card shadow="never" header="商品信息">
+                            <el-form-item label="商品名称" prop="product_name">
+                                <el-input v-model="formData.product_name" maxlength="40" show-word-limit clearable placeholder="请输入"></el-input>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-row :gutter="15">
+                                <el-col :span="formData.product_type==11?8:12">
+                                    <el-form-item label="顾客实际需支付" prop="price">
+                                        <el-input v-model="formData.price" type="number" clearable placeholder="请输入">
+                                            <template #append>元</template>
+                                        </el-input>
+                                        <div class="el-form-item-msg"></div>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="formData.product_type==11?8:12">
+                                    <el-form-item label="划线价" prop="line_price">
+                                        <el-input v-model="formData.line_price" type="number" clearable placeholder="请输入">
+                                            <template #append>元</template>
+                                        </el-input>
+                                        <div class="el-form-item-msg"></div>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="8" v-if="formData.product_type==11">
+                                    <el-form-item label="差价金额" prop="custom_price">
+                                        <el-input v-model="formData.custom_price" type="number" clearable placeholder="请输入">
+                                            <template #append>元</template>
+                                        </el-input>
+                                        <div class="el-form-item-msg"></div>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                            <fieldset>
+                                <legend><el-tag>商品搭配</el-tag></legend>
+                                <el-button type="primary" @click="addSpecs" v-if="specs.length<5">添加分组</el-button>
+                                <div class="specs" v-for="(item,indx) in specs" :key="indx">
+                                    <div class="specs-header">
+                                        <div class="specs-left">
+                                            <el-input v-model="item.name" placeholder="请输入商品组名称" maxlength="10" show-word-limit clearable style="width: 50%;"></el-input>
+                                        </div>
+                                        <div class="specs-right">
+                                            <el-select v-model="item.num" placeholder="请选择">
+                                                <el-option :value="0" label="全部可选"></el-option>
+                                                <el-option :value="len" :label="item.list.length+'选'+len" v-for="len in item.list.length" v-if="item.list.length > 1"></el-option>
+                                            </el-select>
+                                        </div>
+                                    </div>
+                                    <div class="specs-tips">商品组名称中不可出现“任选N”“X选N”字样,当商品组的可选范围是“几选1”或“全部可选”时,不可配置重复选</div>
+                                    <div class="specs-body">
+                                        <div class="body-item" v-for="(its,ind) in item.list" :key="ind">
+                                            <div class="item-left">
+                                                <el-row :gutter="10">
+                                                    <el-col :span="12" class="mb10">
+                                                        <el-input placeholder="请输入单品名称 " v-model="its.name">
+                                                            <template #prepend>名称</template>
+                                                        </el-input>
+                                                    </el-col>
+                                                    <el-col :span="12" class="mb10">
+                                                        <el-input placeholder="单价" v-model="its.price" type="number">
+                                                            <template #prepend>单价</template>
+                                                            <template #append>元</template>
+                                                        </el-input>
+                                                    </el-col>
+                                                    <el-col :span="12" class="mb10">
+                                                        <el-input placeholder="请输入重量 " v-model="its.weight" type="number">
+                                                            <template #prepend>重量</template>
+                                                            <template #append>
+                                                                <el-select v-model="its.weight_unit">
+                                                                    <el-option value="kg" label="kg(千克)"></el-option>
+                                                                    <el-option value="g" label="g(克)"></el-option>
+                                                                    <el-option value="L" label="L(升)"></el-option>
+                                                                    <el-option value="ml" label="ml(毫升)"></el-option>
+                                                                    <el-option value="m" label="m(米)"></el-option>
+                                                                    <el-option value="m²" label="m²(平方米)"></el-option>
+                                                                    <el-option value="m³" label="m³(立方米)"></el-option>
+                                                                </el-select>
+                                                            </template>
+                                                        </el-input>
+                                                    </el-col>
+                                                    <el-col :span="12" class="mb10">
+                                                        <el-input placeholder="数量" v-model="its.number" type="number">
+                                                            <template #prepend>数量</template>
+                                                            <template #append>份</template>
+                                                        </el-input>
+                                                    </el-col>
+                                                </el-row>
+                                            </div>
+                                            <div class="item-dels">
+                                                <el-button type="danger" @click="removeItem(indx,ind)" circle icon="el-icon-delete" size="small"></el-button>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="specs-footer">
+                                         <el-button size="small" type="primary" @click="addItem(indx)">增加单品</el-button>
+                                        <el-button size="small" type="danger" @click="removeSpec(indx)">删除组</el-button>
+                                    </div>
+                                </div>
+                            </fieldset>
+                            <el-form-item label="多规格" prop="mult_sku">
+                                <el-radio-group v-model="formData.mult_sku">
+                                    <el-radio border :label="1">关闭</el-radio>
+                                    <el-radio border :label="2">开启</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <fieldset v-if="formData.mult_sku == 2">
+                                <legend><el-tag>规格明细</el-tag></legend>
+                                <el-button type="primary" @click="addSkuSpecs" v-if="skuSpecs.length<5">新增规格</el-button>
+                                <div class="sku-table">
+                                    <el-table :data="skuSpecs" border>
+                                        <el-table-column prop="image" label="规格图片" width="180">
+                                            <template #default="scope">
+                                                <sc-upload v-model="scope.row.image" title="规格图片" :cropper="true" :compress="1" :aspectRatio="1/1"></sc-upload>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column prop="sku_id" label="商品ID(必填)" width="220">
+                                            <template #default="scope">
+                                                <el-input v-model="scope.row.sku_id" placeholder="商品ID"></el-input>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column prop="name" label="名称(必填)" width="220">
+                                            <template #default="scope">
+                                                <el-input v-model="scope.row.name" maxlength="40" show-word-limit placeholder="SKU名称"></el-input>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column prop="line_price" label="划线价(必填)" width="160">
+                                            <template #default="scope">
+                                                <el-input v-model="scope.row.line_price" type="number" placeholder="划线价">
+                                                    <template #prefix>¥</template>
+                                                </el-input>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column label="支付价(必填)" width="160">
+                                            <template #default="scope">
+                                                <el-input v-model="scope.row.price" :disable="true" readonly placeholder="支付价">
+                                                    <template #prefix>¥</template>
+                                                </el-input>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column prop="custom_price" label="差价(必填)" width="160" v-if="formData.product_type == 11">
+                                            <template #default="scope">
+                                                <el-input v-model="scope.row.custom_price" type="number" placeholder="差价">
+                                                    <template #prefix>¥</template>
+                                                </el-input>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column label="操作" align="left" fixed="right">
+                                            <template #default="scope">
+                                                <el-button type="danger" size="small" @click="removeItemSku(scope.$index)" icon="el-icon-delete">删除</el-button>
+                                                <el-button size="small" @click="itemSkuView(scope.$index,scope.row)">规格详情</el-button>
+                                            </template>
+                                        </el-table-column>
+                                    </el-table>
+                                </div>
+                            </fieldset>
+                            <el-form-item label="商品头图" prop="image_list">
+                                <sc-upload-multiple v-model="formData.image_list" :multiple="false" draggable :limit="10" tip="图片尺寸不超过5M,图片越小呈现的速度越快,建议分辨率不低于750*562px"></sc-upload-multiple>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-form-item label="辅助图" prop="detail_image_list">
+                                <sc-upload-multiple v-model="formData.detail_image_list" :multiple="false" draggable :limit="4" tip="辅助图上传1-4张,每张图片不得超过5M,建议分辨率不低于750*562px"></sc-upload-multiple>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-form-item label="环境图" prop="environment_image_list">
+                                <sc-upload-multiple v-model="formData.environment_image_list" :multiple="false" draggable :limit="10" tip="良好的环境也是用户的优先选择,最多可上传10张。每张图片不得超过5M,建议分辨率不低于750*562px"></sc-upload-multiple>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                        </el-card>
+                        <el-card shadow="never" header="售卖信息">
+                            <el-form-item label="投放渠道" prop="show_channel">
+                                <el-radio-group v-model="formData.show_channel">
+                                    <el-radio :label="1">不限制</el-radio>
+                                    <el-popover placement="top-start" trigger="hover" content="用户仅可在直播间开播时支付购买,售价及库存均仅在直播间渠道生效。用户无法通过收藏或分享的商品链接支付购买。如希望以此售价通过多渠道分享和售卖,投放渠道需选择“不限制”。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="2">
+                                                <template #default>
+                                                    <div class="radio-flex">仅直播间展示 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="用户仅可通过线下二维码等物料购买,商品不会在线上任何渠道展示和售卖。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="5">
+                                                <template #default>
+                                                    <div class="radio-flex">仅线下 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="新用户只可在新人频道购买,售价及库存仅在新人频道生效,用户无法通过收藏或分享的商品链接支付购买。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="7">
+                                                <template #default>
+                                                    <div class="radio-flex">仅新人频道 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="用户可通过线上所有渠道购买(除新人频道),但不可通过线下二维码物料购买。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="8">
+                                                <template #default>
+                                                    <div class="radio-flex">仅线上 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="用户仅可在免费试频道购买,免费价格及库存仅针对参与免费试活动条件的用户生效。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="18">
+                                                <template #default>
+                                                    <div class="radio-flex">仅免费试 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="用户仅可在「团购」页面看到和购买商品。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="22">
+                                                <template #default>
+                                                    <div class="radio-flex">仅团购商城 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="商品售卖日期内,用户仅在直播间和获客卡渠道可支付购买,售价及库存均仅在直播间和获客卡渠道生效。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="23">
+                                                <template #default>
+                                                    <div class="radio-flex">直播间+获客卡 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="该渠道商品不会在常规渠道售卖,需报名参加营销活动进行售卖。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="25">
+                                                <template #default>
+                                                    <div class="radio-flex">仅活动报名 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-form-item label="库存数量" prop="limit_use_rule">
+                                <el-radio-group v-model="formData.limit_use_rule">
+                                    <el-radio :label="2">不限制</el-radio>
+                                    <el-radio :label="1">限库存</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                                <div class="date-list" v-if="formData.limit_use_rule==1">
+                                    <el-form-item label="" prop="use_num_per_consume">
+                                        <el-input v-model="formData.use_num_per_consume">
+                                            <template #append>份</template>
+                                            <template #prepend>团购库存数量</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="商品售卖日期" prop="sold_start_times">
+                                <div style="width: 30%;">
+                                    <el-date-picker v-model="formData.sold_start_times" placeholder="请选择商品售卖日期" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" />
+                                </div>
+                                <div class="el-form-item-msg">顾客可以在这个时间内购买商品,超过这个日期,活动自动下线</div>
+                                <div class="radio-flex">
+                                    自动延期<el-switch active-text="开" inactive-text="关" inline-prompt v-model="formData.auto_renew" style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" :active-value="1" :inactive-value="0"/>
+                                    <span class="fs12">团购到期后自动延长30天(有效期同时延长),可随时关闭。</span>
+                                </div>
+                            </el-form-item>
+                        </el-card>
+                        <el-card shadow="never" header="交易规则">
+                            <el-form-item label="顾客可消费日期" prop="use_date_type">
+                                <el-radio-group v-model="formData.use_date_type">
+                                    <el-radio :label="1">指定天数</el-radio>
+                                    <el-radio :label="2">指定日期</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg" v-if="formData.use_date_type==1"></div>
+                                <div class="el-form-item-msg" v-if="formData.use_date_type==2">
+                                    可使用日期的结束时间必须晚于售卖日期的结束时间
+                                </div>
+                                <div class="date-list" v-if="formData.use_date_type==1">
+                                    <el-input v-model="formData.day_duration">
+                                        <template #append>天,购买当日默认可用</template>
+                                        <template #prepend>自购买次日起</template>
+                                    </el-input>
+                                </div>
+                                <div class="date-list" v-if="formData.use_date_type==2">
+                                    <el-date-picker v-model="formData.use_times" placeholder="请选择商品售卖日期" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" />
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="顾客信息设置" prop="customer_reserved_info">
+                                <el-radio-group v-model="formData.customer_reserved_info" disabled>
+                                    <el-radio :label="1">不需要</el-radio>
+                                    <el-radio :label="2">需要顾客手机号码</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-form-item label="顾客不可消费日期" prop="can_no_use_date">
+                                <el-radio-group v-model="formData.can_no_use_date">
+                                    <el-radio :label="1">所有日期均可使用</el-radio>
+                                    <el-radio :label="2">部分日期不可用</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                                <template v-if="formData.can_no_use_date==2">
+                                    <div class="date-list">
+                                        <div class="date-type-item">
+                                            <div class="item-header"><el-checkbox v-model="formData.can_no_use_week" :value="1" label="每周几不可用" /></div>
+                                            <div class="item-body" style="width: 500px;" v-if="formData.can_no_use_week">
+                                                <el-form-item label="" prop="no_use_weeks">
+                                                    <el-select v-model="formData.no_use_weeks" multiple placeholder="请选择" style="width:100%">
+                                                        <el-option v-for="(item,index) in weeksData" :key="index" :label="item.name" :value="item.key"></el-option>
+                                                    </el-select>
+                                                </el-form-item>
+                                            </div>
+                                        </div>
+                                        <!-- <div class="date-type-item">
+                                            <div class="item-header"><el-checkbox v-model="formData.can_no_use_holiday" :value="1" label="节假日不可用" /></div>
+                                            <div class="item-body" style="width: 500px;" v-if="formData.can_no_use_holiday">
+                                                <el-form-item label="" prop="no_use_holidays">
+                                                    <el-select v-model="formData.no_use_holidays" multiple placeholder="请选择" style="width:100%">
+                                                        <el-option v-for="(item,index) in holiday" :key="index" :label="item.name" :value="item.key"></el-option>
+                                                    </el-select>
+                                                </el-form-item>
+                                            </div>
+                                        </div> -->
+                                        <div class="date-type-item">
+                                            <div class="item-header"><el-checkbox v-model="formData.can_no_use_day" :value="1" label="指定某天不可用" /></div>
+                                            <div class="item-body" style="width: 500px;" v-if="formData.can_no_use_day">
+                                                <el-form-item label="" prop="no_use_days">
+                                                    <el-date-picker
+                                                        v-model="formData.no_use_days"
+                                                        type="dates"
+                                                        style="width:100%"
+                                                        placeholder="请选择日期"
+                                                    />
+                                                </el-form-item>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </template>
+                            </el-form-item>
+                            <!-- <el-form-item label="券码类型" prop="code_source_type">
+                                <el-radio-group v-model="formData.code_source_type">
+                                    <el-radio :label="1">抖音码</el-radio>
+                                    <el-radio :label="2">三方码</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item> -->
+                            
+                        </el-card>
+                        <el-card shadow="never" header="消费规则">
+                            <el-form-item label="使用规则">
+                                <div class="el-form-item-msg">
+                                    <el-button @click="addRule">添加规则</el-button>
+                                </div>
+                                <div class="date-list" style="margin-top: 10px;" v-if="notificationData.length > 0">
+                                    <div class="date-type-item flex" v-for="(item,index) in notificationData" :key="index">
+                                        <div class="left">
+                                            <el-input v-model="item.title" placeholder="请输入标题" />
+                                            <el-input v-model="item.content" placeholder="请输入规则内容" />
+                                        </div>
+                                        <div class="right">
+                                            <el-button type="danger" size="small" @click="removeRule(index)" circle icon="el-icon-delete"></el-button>
+                                        </div>
+                                    </div>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="限购规则" prop="limit_rule_type">
+                                <el-radio-group v-model="formData.limit_rule_type">
+                                    <el-radio :label="1">不限制购买</el-radio>
+                                    <el-radio :label="2">限制购买</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                                <div class="date-list" v-if="formData.limit_rule_type==2">
+                                    <el-input v-model="formData.limit_rule">
+                                        <template #append>份</template>
+                                        <template #prepend>限制每人最多购买</template>
+                                    </el-input>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="预约规则" prop="booking_type">
+                                <el-radio-group v-model="formData.booking_type">
+                                    <el-radio :label="1">无需预约</el-radio>
+                                    <el-radio :label="2">到店前需要预约</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                                <div class="date-list" v-if="formData.booking_type==2">
+                                    <el-input v-model="formData.booking_date">
+                                        <template #prepend>需提前</template>
+                                        <template #append>
+                                            <el-select v-model="formData.booking_unit" style="width: 80px;">
+                                                <el-option :value="1" label="天"></el-option>
+                                                <el-option :value="2" label="小时"></el-option>
+                                            </el-select>
+                                        </template>
+                                    </el-input>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="使用张数限制" prop="rec_person_type">
+                                <el-radio-group v-model="formData.rec_person_type">
+                                    <el-radio :label="1">不限制张数</el-radio>
+                                    <el-radio :label="2">限制张数</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                                <div class="date-list" v-if="formData.rec_person_type==2">
+                                    <el-input v-model="formData.rec_person_num_max">
+                                        <template #prepend>单次消费最多使用张数</template>
+                                        <template #append>张</template>
+                                    </el-input>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="库存方式" prop="stock_type">
+                                <el-radio-group v-model="formData.stock_type">
+                                    <el-radio :label="1">付款减库存</el-radio>
+                                    <el-radio :label="2">核销减库存</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg">
+                                    <span v-if="formData.stock_type==1">用户在小程序支付成功后,已售数量增加,库存减少,不限库存不受影响</span>
+                                    <span v-if="formData.stock_type==2">用户在完成订单核销后,已售数量增加,库存减少,不限库存不受影响</span>
+                                </div>
+                            </el-form-item>
+                        </el-card>
+                        </template>
+                    </el-form>
+                </el-col>
+                <el-col :span="6">
+                    <el-card shadow="never" header="详情预览">
+                        <div class="sub-tips">该功能只做预览,实际效果以真机为准</div>
+                        <div class="preview-mobile">
+                            <div class="mobile-bannber">
+                                <el-carousel :interval="5000" arrow="always">
+                                    <el-carousel-item v-for="item in formData.image_list" :key="item">
+                                        <el-image :src="item.url"></el-image>
+                                    </el-carousel-item>
+                                </el-carousel>
+                            </div>
+                            <div class="mobile-info">
+                                <div class="info-price">
+                                    <span class="price">{{ formData.price?$TOOL.moneyFormat(formData.price):'¥0.00' }}</span>
+                                    <span class="line">{{ formData.line_price?$TOOL.moneyFormat(formData.line_price):'¥0.00' }}</span>
+                                    <span class="dis">{{ $TOOL.disFormat(formData.price,formData.line_price) }}折</span>
+                                </div>
+                                <div class="info-title">{{ formData.product_name?formData.product_name:'演示商品标题' }}</div>
+                                <div class="sku-list" v-if="skuSpecs.length > 0">
+                                    <div class="sku-title">规格<br>选择</div>
+                                    <div class="sku-list-body">
+                                        <div class="sku-item" v-for="(item,indx) in skuSpecs" :key="indx">{{item.name}}</div>
+                                    </div>
+                                </div>
+                                <div class="item-tag">
+                                    <div class="tag-li"><el-icon color="#f00" size="14"><el-icon-circle-check /></el-icon>过期退</div>
+                                    <div class="tag-li"><el-icon color="#f00" size="14"><el-icon-circle-check /></el-icon>随时退</div>
+                                </div>
+                            </div>
+                            <div class="mobile-group">
+                                <div class="group-title">团购套餐</div>
+                                <div class="group-body" v-if="specs.length > 0" v-for="(item,indx) in specs" :key="indx">
+                                    <div class="body-title">
+                                        {{item.name}}
+                                        <span v-if="item.num == 0">全部可选</span>
+                                        <span v-else>{{item.list.length}}选{{item.num}}</span>
+                                    </div>
+                                    <div class="body-item">
+                                        <div class="body-item-li" v-for="(its,idx) in item.list" :key="idx">
+                                            {{its.name}}
+                                            <div class="item-right">
+                                                <span>({{its.number}}份)</span>
+                                                <span>{{$TOOL.moneyFormat(its.price)}}</span>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="mobile-group">
+                                <div class="group-title">购买须知</div>
+                                <div class="group-mix">
+                                    <div class="mix-title">
+                                        <el-icon size="14" color="#000"><el-icon-suitcase /></el-icon>有效期
+                                    </div>
+                                    <div class="mix-item" v-if="formData.use_date_type==1">
+                                        购买后 <span>{{ formData.day_duration }}</span> 天有效
+                                    </div>
+                                    <div class="mix-item" v-if="formData.use_date_type==2">
+                                        <span v-if="formData.use_times">
+                                        {{ $TOOL.dateFormat(formData.use_times[0],'yyyy-MM-dd') }}至{{ $TOOL.dateFormat(formData.use_times[1],'yyyy-MM-dd') }}
+                                        </span>
+                                    </div>
+                                </div>
+                                <div class="group-mix">
+                                    <div class="mix-title">
+                                        <el-icon size="14" color="#000"><el-icon-clock /></el-icon>可用时间
+                                    </div>
+                                    <div class="mix-item" v-if="formData.can_no_use_date==1">
+                                        商家营业时间可用
+                                    </div>
+                                </div>
+                                <div class="group-mix">
+                                    <div class="mix-title">
+                                        <el-icon size="14" color="#000"><el-icon-alarm-clock /></el-icon>预约规则
+                                    </div>
+                                    <div class="mix-item" v-if="formData.booking_type==1">
+                                        无需预约,高峰期可能需要排队
+                                    </div>
+                                    <div class="mix-item" v-if="formData.booking_type==2">
+                                        需要提前<span>{{ formData.booking_date }}</span>{{ formData.booking_unit==1?'天':'小时' }}预约
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </el-card>
+                </el-col>
+            </el-row>
+        </el-main>
+        <el-footer style="text-align: center;">
+            <el-button @click="reback" size="large">取 消</el-button>
+            <el-button size="large" type="primary" :loading="isSaveing" @click="submit()">提交审核</el-button>
+        </el-footer>
+    </el-container>
+    <skuView ref="skuView" @success="skuResp"></skuView>
+</template>
+
+<script>
+import dayjs from 'dayjs';
+import skuView from './components/sku'
+export default {
+    components:{
+        skuView
+    },
+    data(){
+        return {
+            isSaveing:false,
+            showNext:false,
+            formData:{
+                settle_type:2,
+                show_channel:1,
+                limit_use_rule:2,
+                customer_reserved_info:2,
+                auto_renew:1,
+                use_date_type:1,
+                day_duration:30,
+                can_no_use_date:1,
+                code_source_type:1,
+                limit_rule_type:1,
+                limit_rule:1,
+                booking_date:1,
+                booking_type:1,
+                booking_unit:1,
+                rec_person_type:1,
+                rec_person_num_max:1,
+                image_list:[],
+                detail_image_list:[],
+                environment_image_list:[],
+                mult_sku:1,
+                stock_type:1
+            },
+            holiday:[{'key':1,"name":"元旦"},{'key':2,"name":"春节"},{'key':3,"name":"清明"},{'key':4,"name":"劳动节"},{'key':5,"name":"端午节"},{'key':6,"name":"中秋节"},{'key':7,"name":"国庆节"},{'key':8,"name":"情人节"},{'key':9,"name":"圣诞节"},{'key':10,"name":"元宵节"},{'key':11,"name":"520"},{'key':12,"name":"儿童节"},{'key':13,"name":"七夕节"},{'key':14,"name":"二月二"},{'key':15,"name":"母亲节"},{'key':16,"name":"父亲节"},{'key':17,"name":"教师节"}],
+            weeksData:[{'key':1,"name":"星期一"},{'key':2,"name":"星期二"},{'key':3,"name":"星期三"},{'key':4,"name":"星期四"},{'key':5,"name":"星期五"},{'key':6,"name":"星期六"},{'key':7,"name":"星期天"},],
+            notificationData:[{"title":"","content":""}],
+            specs:[{"name":"","num":0,"list":[ {"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1} ]}],
+            skuSpecs:[],
+            channelLoad:false,
+            rules:{
+                custom_price: [
+                    {required: true, message: '请输入'}
+                ],
+                no_use_weeks: [
+                    {required: true, message: '请选择'}
+                ],
+                no_use_holidays: [
+                    {required: true, message: '请选择'}
+                ],
+                no_use_days: [
+                    {required: true, message: '请选择'}
+                ],
+                customer_reserved_info: [
+                    {required: true, message: '请选择'}
+                ],
+                line_price: [
+                    {required: true, message: '请输入'}
+                ],
+                price: [
+                    {required: true, message: '请输入'}
+                ],
+                image_list: [
+                    {required: true, message: '请上传'}
+                ],
+                rec_person_type: [
+                    {required: true, message: '请选择'}
+                ],
+                code_source_type: [
+                    {required: true, message: '请选择'}
+                ],
+                can_no_use_date: [
+                    {required: true, message: '请选择'}
+                ],
+                use_date_type: [
+                    {required: true, message: '请选择'}
+                ],
+                product_name: [
+                    {required: true, message: '请输入'}
+                ],
+                use_num_per_consume: [
+                    {required: true, message: '请输入'}
+                ],
+                limit_use_rule: [
+                    {required: true, message: '请选择'}
+                ],
+                sold_start_times: [
+                    {required: true, message: '请选择'}
+                ],
+                show_channel: [
+                    {required: true, message: '请选择'}
+                ],
+                settle_type: [
+                    {required: true, message: '请选择'}
+                ],
+                category: [
+                    {required: true, message: '请选择'}
+                ],
+                product_type: [
+                    {required: true, message: '请选择'}
+                ],
+                stock_type: [
+                    {required: true, message: '请选择'}
+                ],
+            },
+            deptsProps:{
+                value: "category_id",
+                label: "name"
+            },
+            typeData:null,
+            categoryData:[]
+        }
+    },
+    created(){
+        this.getData()
+        this.formData.sold_start_times = this.formattedCurrentDate();
+    },
+    methods: {
+        addRule(){
+            this.notificationData.push({"title":"","content":""});
+        },
+        removeRule(index){
+            if (this.notificationData.length <= 1) {
+                return this.$message.error("至少保留一条规则")
+            }
+            this.notificationData.splice(index,1)
+        },
+        skuResp(data){
+            this.skuSpecs[data.index] = data.data;
+        },
+        itemSkuView(index,data){
+            this.$nextTick(() => {
+                this.$refs.skuView.open("edit").setData(index,data)
+            })
+        },
+        addSkuSpecs(){
+            if(!this.formData.price) return this.$message.error("请先设置顾客实际需支付金额");
+            this.skuSpecs.push({"image":"","sku_id":this.generate(),"name":"","line_price":1,"custom_price":1,"price":this.formData.price,"is_default":false,"specs":[]});
+        },
+        removeItemSku(index){
+            this.skuSpecs.splice(index,1)
+        },
+        addSpecs(){
+            if (this.specs.length >= 5) {
+                return this.$message.error("最多只能添加三组规格")
+            }
+            this.specs.push({"name":"","num":0,"list":[ {"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1} ]});
+        },
+        addItem(index){
+            if (this.specs[index].list.length >= 20) {
+                return this.$message.error("最多只能添加20个")
+            }
+            this.specs[index].list.push({"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1})
+        },
+        removeSpec(index){
+            this.specs.splice(index,1)
+        },
+        removeItem(index,sub){
+            this.specs[index].list.splice(sub,1)
+        },
+        generate() {
+            let timestamp = Date.now();
+            if (timestamp === this.lastTimestamp) {
+                this.sequence++;
+            } else {
+                this.sequence = 0;
+                this.lastTimestamp = timestamp;
+            }
+            const randomPart = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
+            const timestampPart = timestamp.toString().slice(-6);   // 取时间戳后6位
+            const seqPart = this.sequence.toString().padStart(2, '0'); // 序列号占2位(0-99)
+            let base = timestampPart + seqPart + randomPart; // 6+2+4=12位
+            const remainingLength = 18 - base.length;
+            const extraRandom = Math.floor(Math.random() * Math.pow(10, remainingLength)).toString().padStart(remainingLength, '0');
+            return base + extraRandom; // 最终18位字符串
+        },
+        formattedCurrentDate() {
+            const now = dayjs();
+            const currentDate = now.format('YYYY-MM-DD HH:mm:ss');
+            const nextYearDate = now.add(1, 'year').format('YYYY-MM-DD HH:mm:ss');
+            return [currentDate,nextYearDate];
+        },
+        async getTemplate(v){
+            const nodes = this.$refs.cascaderRef.getCheckedNodes()
+            var typeData = this.$TOOL.findNodeById(this.categoryData,nodes[0].value);
+            if (!typeData) return this.$message.error("获取商品类型失败")
+            this.typeData = typeData.types;
+            this.showNext = true;
+            // var { formData, $message } = this;
+            // if (formData.product_type && formData.category) {
+            //     // var resp = await this.$API.merGoods.template.post({"product_type":formData.product_type,"category":formData.category});
+            //     this.showNext = true;
+            //     return ;
+            // }
+        },
+        async getData(){
+            this.channelLoad = true;
+            var resp = await this.$API.merGoods.category.get();
+            this.channelLoad = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg)
+            }
+            this.categoryData = resp.data;
+            // this.getCate()
+        },
+        async getCate(){
+            var resp = await this.$API.merGoods.type.get();
+            this.channelLoad = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg)
+            }
+            this.typeData = resp.data;
+        },
+        reback(){
+            this.$confirm(`确定要退出添加商品吗?`, '提示', {
+                type: 'warning'
+            }).then(() => {
+                this.$router.go(-1)
+            }).catch(() => {
+
+            })
+        },
+        async submit(){
+            var { formData, $message } = this;
+            var validate = await this.$refs.dialogForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            if (this.notificationData.length == 0) {
+                return this.$message.error("使用规则至少需要一组以上");
+            }
+            formData.specs = this.specs;
+            formData.notification = this.notificationData;
+            formData.skuSpecs = this.skuSpecs;
+            if (formData.sold_start_times) {
+                var sold_start_time = formData.sold_start_times;
+                formData.sold_start_time = this.$TOOL.dateFormat(sold_start_time[0],"yyyy-MM-dd")
+                formData.sold_end_time = this.$TOOL.dateFormat(sold_start_time[1],"yyyy-MM-dd")
+            }
+            if (formData.use_times) {
+                var use_time = formData.use_times;
+                formData.use_time_start = this.$TOOL.dateFormat(use_time[0],"yyyy-MM-dd")
+                formData.use_time_end = this.$TOOL.dateFormat(use_time[1],"yyyy-MM-dd")
+            }
+            this.isSaveing = true;
+            var resp = await this.$API.merGoods.save.post(formData);
+            this.isSaveing = false;
+            if (resp.code == 0) {
+                return $message.error(resp.msg)
+            }
+            $message.success(resp.msg)
+            this.$router.go(-1)
+        }
+    }
+}
+</script>
+
+
+<style scoped>
+.group-mix .mix-title{display: flex;align-items: center;line-height: 32px;font-weight: bold;font-size: 12px;gap: 5px;}
+.group-mix .mix-item{padding-left: 10px;position: relative;line-height: 32px;margin-left: 10px;}
+.group-mix .mix-item span{color: orange;padding: 0 5px;}
+.group-mix .mix-item::after{position: absolute;top: 0;width: 5px;height: 5px;background-color: #000;border-radius: 5px;content: "";left: 0;top: 38%;}
+.mobile-group{background-color: #fff;margin-top: 10px;padding: 10px;}
+.mobile-group .group-title{font-size: 14px;font-weight: bold;color: #333;line-height: 36px;}
+.mobile-group .body-title{display: flex;align-items: center;line-height: 32px;font-size: 14px;color: #333;font-weight: bold;gap: 8px;}
+.mobile-group .body-title span{font-size: 12px;font-weight: normal;color: #666;}
+.mobile-group .body-item-li{display: flex;align-items: center;justify-content: space-between;line-height: 32px;font-size: 12px;color: #333;font-weight: bold;}
+.mobile-group .body-item-li .item-right{display: flex;align-items: center;gap: 10px;}
+
+.date-list{background-color: var(--el-fill-color-light);padding: 10px;border-radius: 2px;min-width: 500px;}
+.date-type-item{margin-bottom: 15px;}
+.date-type-item.flex{display: flex;align-items: center;gap: 10px;justify-content: space-between;}
+.date-type-item.flex .left{flex: 1;}
+
+.mobile-bannber{background-color: #f8f8f8;}
+.mobile-info{padding: 10px;background-color: #fff;}
+.mobile-info .info-title{font-size: 14px;font-weight: bold;line-height: 36px;}
+.mobile-info .info-price{display: flex;align-items: flex-end;gap: 8px;}
+.mobile-info .info-price .price{color: #f00;font-size: 22px;font-weight: bold;}
+.mobile-info .info-price .line{color: #666;font-size: 12px;text-decoration:line-through;}
+.mobile-info .info-price .dis{background-color: rgb(255, 234, 234);;color: rgb(255, 68, 68);;padding: 5px;border-radius: 2px;}
+.mobile-info .item-tag{display: flex;align-items: center;gap: 10px;font-size: 12px;}
+.mobile-info .item-tag .tag-li{display: flex;align-items: center;gap: 5px;}
+.mobile-info .sku-list{display: flex;align-items: center;margin: 10px 0;}
+.mobile-info .sku-list .sku-title{color: #999090;font-size: 12px;}
+.mobile-info .sku-list .sku-list-body{display: flex;align-items: center;margin-left: 8px;flex: 1;overflow: hidden;overflow-x: auto;gap: 8px;}
+.mobile-info .sku-list .sku-list-body .sku-item{background-color: #f6fafd;padding: 8px 16px;border-radius: 8px;text-wrap: nowrap;}
+
+.preview-mobile{margin-top: 10px;box-shadow: 0 20px 30px 0 rgb(63 63 65 / 6%);border-radius: 10px;border: 1px solid #f8f8f8;box-sizing: border-box;background-color: #f8f8f8;}
+.radio-flex{display: flex;align-items: center;gap: 5px;}
+.fs12{color: #999;font-size: 12px;}
+
+.specs{margin-top: 15px;background-color: #f8f8f8;}
+.specs-header{
+    display: flex;
+    background-color: #ddd;
+    padding: 10px;
+}
+.specs-tips{
+    padding: 0 10px 10px 10px;
+    background-color: #ddd;
+}
+.specs-header .specs-left{
+    display: flex;
+    align-items: center;
+    flex: 1;
+    gap: 10px;
+}
+.specs-header .specs-right{
+    display: flex;
+    margin-left: auto;
+    margin-right: 0;
+}
+.specs-body{display: flex;align-items: center;gap: 10px;padding: 10px;flex-direction: row;flex-wrap: wrap;}
+.specs-body .body-item{padding: 5px;display: flex;align-items: center;}
+.specs-body .body-item .item-dels{margin-left: 10px;}
+.item-img{margin-bottom: 5px;}
+.mb10{margin-bottom: 10px;}
+.specs-footer{background-color: #ddd;padding: 10px;}
+.sku-table{margin-top: 10px;}
+.el-upload__tip,
+.el-upload-list__item,
+.el-dialog__wrapper {
+    z-index: 9999 !important;
+}
+</style>

+ 254 - 0
src/views/manage/goods/op/components/sku.vue

@@ -0,0 +1,254 @@
+<template>
+    <el-drawer :title="titleMap[mode]" :append-to-body="true" v-model="visible" :size="800" destroy-on-close :close-on-click-modal="false" @closed="$emit('closed')" :with-header="false">
+        <el-container class="flex-column" v-loading="loading">
+            <div class="drawer-detail-main">
+                <div class="drawer-detail-header">
+                    <div class="drawer-detail-header-body">
+                        <div class="drawer-detail-header-left">{{ titleMap[mode] }}</div>
+                        <div class="drawer-detail-header-left">
+                            <el-button type="default" icon="el-icon-close" @click="visible=false"></el-button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <el-main>
+                <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
+                    <fieldset>
+                        <legend><el-tag>基础信息</el-tag></legend>
+                        <el-form-item label="SKU名称" prop="name">
+                            <el-input v-model="formData.name" clearable maxlength="40" show-word-limit placeholder="请输入"></el-input>
+                            <div class="el-form-item-msg"></div>
+                        </el-form-item>
+                        <el-form-item label="商品原价" prop="line_price">
+                            <el-input v-model="formData.line_price" clearable placeholder="请输入" type="number">
+                                <template #append>元</template>
+                            </el-input>
+                            <div class="el-form-item-msg"></div>
+                        </el-form-item>
+                        <el-form-item label="顾客支付价" prop="price">
+                            <el-input v-model="formData.price" readonly clearable placeholder="请输入" type="number">
+                                <template #append>元</template>
+                            </el-input>
+                            <div class="el-form-item-msg"></div>
+                        </el-form-item>
+                        <el-form-item label="商品编号" prop="sku_id">
+                            <el-input v-model="formData.sku_id" clearable placeholder="请输入">
+                                <template #append>
+                                    <el-button @click="createSkuId">重新获取</el-button>
+                                </template>
+                            </el-input>
+                            <div class="el-form-item-msg"></div>
+                        </el-form-item>
+                        <el-form-item label="规格图片" prop="image">
+                            <sc-upload v-model="formData.image" title="规格图片" :cropper="true" :compress="1" :aspectRatio="1/1"></sc-upload>
+                            <div class="el-form-item-msg"></div>
+                        </el-form-item>
+                    </fieldset>
+                    <fieldset>
+                        <legend><el-tag>商品搭配</el-tag></legend>
+                        <el-button type="primary" size="small" @click="addSpecs" v-if="specs.length<5">添加分组</el-button>
+                        <div class="specs" v-for="(item,indx) in specs" :key="indx">
+                            <div class="specs-header">
+                                <div class="specs-left">
+                                    <el-input v-model="item.name" placeholder="请输入商品组名称" maxlength="10" show-word-limit clearable style="width: 50%;"></el-input>
+                                </div>
+                                <div class="specs-right">
+                                    <el-select v-model="item.num" placeholder="请选择">
+                                        <el-option :value="0" label="全部可选"></el-option>
+                                        <el-option :value="len" :label="item.list.length+'选'+len" v-for="len in item.list.length" v-if="item.list.length > 1"></el-option>
+                                    </el-select>
+                                </div>
+                            </div>
+                            <div class="specs-tips">商品组名称中不可出现“任选N”“X选N”字样,当商品组的可选范围是“几选1”或“全部可选”时,不可配置重复选</div>
+                            <div class="specs-body">
+                                <div class="body-item" v-for="(its,ind) in item.list" :key="ind">
+                                    <div class="item-left">
+                                        <el-row :gutter="10">
+                                            <el-col :span="12" class="mb10">
+                                                <el-input placeholder="请输入单品名称 " v-model="its.name">
+                                                    <template #prepend>名称</template>
+                                                </el-input>
+                                            </el-col>
+                                            <el-col :span="12" class="mb10">
+                                                <el-input placeholder="单价" v-model="its.price" type="number">
+                                                    <template #prepend>单价</template>
+                                                    <template #append>元</template>
+                                                </el-input>
+                                            </el-col>
+                                            <el-col :span="12" class="mb10">
+                                                <el-input placeholder="请输入重量 " v-model="its.weight" type="number">
+                                                    <template #prepend>重量</template>
+                                                    <template #append>
+                                                        <el-select v-model="its.weight_unit">
+                                                            <el-option value="kg" label="kg(千克)"></el-option>
+                                                            <el-option value="g" label="g(克)"></el-option>
+                                                            <el-option value="L" label="L(升)"></el-option>
+                                                            <el-option value="ml" label="ml(毫升)"></el-option>
+                                                            <el-option value="m" label="m(米)"></el-option>
+                                                            <el-option value="m²" label="m²(平方米)"></el-option>
+                                                            <el-option value="m³" label="m³(立方米)"></el-option>
+                                                        </el-select>
+                                                    </template>
+                                                </el-input>
+                                            </el-col>
+                                            <el-col :span="12" class="mb10">
+                                                <el-input placeholder="数量" v-model="its.number" type="number">
+                                                    <template #prepend>数量</template>
+                                                    <template #append>份</template>
+                                                </el-input>
+                                            </el-col>
+                                        </el-row>
+                                    </div>
+                                    <div class="item-dels">
+                                        <el-button type="danger" @click="removeItem(indx,ind)" circle icon="el-icon-delete" size="small"></el-button>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="specs-footer">
+                                <el-button type="primary" @click="addItem(indx)" size="small">增加单品</el-button>
+                                <el-button type="danger" @click="removeSpec(indx)" size="small">删除组</el-button>
+                            </div>
+                        </div>
+                    </fieldset>
+                </el-form>
+            </el-main>
+            <el-footer style="text-align: right;">
+                <el-button @click="visible=false" >取 消</el-button>
+                <el-button v-if="mode!='show'" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
+            </el-footer>
+        </el-container>
+    </el-drawer>
+</template>
+
+<script>
+export default {
+    
+    data(){
+        return {
+            loading: false,
+            mode:"add",
+            titleMap:{
+                add:"新增商品",
+                edit:"SKU详情"
+            },
+            visible: false,
+            isSaveing: false,
+            specs:[{"name":"","num":0,"list":[ {"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1} ]}],
+            formData:{},
+            skuIndex:0,
+            rules:{
+                sku_id: [
+                    {required: true, message: '请输入'}
+                ],
+                name: [
+                    {required: true, message: '请输入'}
+                ],
+                line_price: [
+                    {required: true, message: '请输入'}
+                ],
+                price: [
+                    {required: true, message: '请输入'}
+                ],
+            }
+        }
+    },
+    methods:{
+        createSkuId(){
+            this.formData.sku_id = this.generate()
+        },
+        generate() {
+            // 1. 获取当前毫秒时间戳(13位)
+            let timestamp = Date.now();
+            // 避免同一毫秒内重复(若时间戳相同,sequence递增)
+            if (timestamp === this.lastTimestamp) {
+                this.sequence++;
+            } else {
+                this.sequence = 0;
+                this.lastTimestamp = timestamp;
+            }
+            
+            // 2. 随机数部分:生成 4 位随机数(保证总长度灵活调整)
+            const randomPart = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
+            
+            // 3. 组合:时间戳(13位) + 序列号(最多2位,可调) + 随机数(4位) → 总长度可变
+            //    目标18位,所以需要控制各部分长度
+            //    这里设计:时间戳后6位 + 序列号(2位) + 随机数(4位) + 补足剩余长度
+            const timestampPart = timestamp.toString().slice(-6);   // 取时间戳后6位
+            const seqPart = this.sequence.toString().padStart(2, '0'); // 序列号占2位(0-99)
+            
+            // 组合得到12位,还需要6位随机数(总18位)
+            let base = timestampPart + seqPart + randomPart; // 6+2+4=12位
+            const remainingLength = 18 - base.length;
+            const extraRandom = Math.floor(Math.random() * Math.pow(10, remainingLength)).toString().padStart(remainingLength, '0');
+            
+            return base + extraRandom; // 最终18位字符串
+        },
+        open(mode = 'add'){
+            this.mode = mode;
+            this.visible = true;
+            return this
+        },
+        //表单注入数据
+        setData(index,data){
+            this.formData = JSON.parse(JSON.stringify(data));
+            this.specs = this.formData.specs;
+            this.skuIndex = index;
+        },
+        addSpecs(){
+            if (this.specs.length >= 5) {
+                return this.$message.error("最多只能添加三组规格")
+            }
+            this.specs.push({"name":"","num":0,"list":[ {"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1} ]});
+        },
+        addItem(index){
+            if (this.specs[index].list.length >= 20) {
+                return this.$message.error("最多只能添加20个")
+            }
+            this.specs[index].list.push({"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1})
+        },
+        removeSpec(index){
+            this.specs.splice(index,1)
+        },
+        removeItem(index,sub){
+            this.specs[index].list.splice(sub,1)
+        },
+        async submit(){
+            var validate = await this.$refs.dialogForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            this.visible = false;
+            this.$emit("success",{"index":this.skuIndex,"data":this.formData});
+            this.formData = {};
+        }
+    }
+}
+</script>
+
+<style>
+.specs{margin-top: 15px;background-color: #f8f8f8;}
+.specs-header{
+    display: flex;
+    background-color: #ddd;
+    padding: 10px;
+}
+.specs-tips{
+    padding: 0 10px 10px 10px;
+    background-color: #ddd;
+}
+.specs-header .specs-left{
+    display: flex;
+    align-items: center;
+    flex: 1;
+    gap: 10px;
+}
+.specs-header .specs-right{
+    display: flex;
+    margin-left: auto;
+    margin-right: 0;
+}
+.specs-body{display: flex;align-items: center;gap: 10px;padding: 10px;flex-direction: row;flex-wrap: wrap;}
+.specs-body .body-item{padding: 5px;display: flex;align-items: center;}
+.specs-body .body-item .item-dels{margin-left: 10px;}
+.mb10{margin-bottom: 10px;}
+.specs-footer{background-color: #ddd;padding: 10px;}
+.sku-table{margin-top: 10px;}
+</style>

+ 872 - 0
src/views/manage/goods/op/edit.vue

@@ -0,0 +1,872 @@
+<template>
+    <el-container>
+        <el-main>
+            <el-row :gutter="20">
+                <el-col :span="18">
+                    <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="140px" label-position="right">
+                        <el-card shadow="never" header="商品类型">
+                            <el-form-item label="商品品类" prop="category" v-loading="channelLoad">
+                                <el-cascader ref="cascaderRef" v-model="formData.category" :options="categoryData" :props="deptsProps" @change="getTemplate" clearable style="width: 50%;" />
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-form-item label="商品类型" prop="product_type" v-if="typeData">
+                                <el-radio-group v-model="formData.product_type">
+                                    <el-radio border :label="item.key" v-for="(item,index) in typeData" :key="index">{{item.name}}</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                        </el-card>
+                        <template v-if="showNext">
+                        <el-card shadow="never" header="商品信息">
+                            <el-form-item label="商品名称" prop="product_name">
+                                <el-input v-model="formData.product_name" maxlength="40" show-word-limit clearable placeholder="请输入"></el-input>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-row :gutter="15">
+                                <el-col :span="formData.product_type==11?8:12">
+                                    <el-form-item label="顾客实际需支付" prop="price">
+                                        <el-input v-model="formData.price" type="number" clearable placeholder="请输入">
+                                            <template #append>元</template>
+                                        </el-input>
+                                        <div class="el-form-item-msg"></div>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="formData.product_type==11?8:12">
+                                    <el-form-item label="划线价" prop="line_price">
+                                        <el-input v-model="formData.line_price" type="number" clearable placeholder="请输入">
+                                            <template #append>元</template>
+                                        </el-input>
+                                        <div class="el-form-item-msg"></div>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="8" v-if="formData.product_type==11">
+                                    <el-form-item label="差价金额" prop="custom_price">
+                                        <el-input v-model="formData.custom_price" type="number" clearable placeholder="请输入">
+                                            <template #append>元</template>
+                                        </el-input>
+                                        <div class="el-form-item-msg"></div>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                            <fieldset>
+                                <legend><el-tag>商品搭配</el-tag></legend>
+                                <el-button type="primary" @click="addSpecs" v-if="specs.length<5">添加分组</el-button>
+                                <div class="specs" v-for="(item,indx) in specs" :key="indx">
+                                    <div class="specs-header">
+                                        <div class="specs-left">
+                                            <el-input v-model="item.name" placeholder="请输入商品组名称" maxlength="10" show-word-limit clearable style="width: 50%;"></el-input>
+                                        </div>
+                                        <div class="specs-right">
+                                            <el-select v-model="item.num" placeholder="请选择">
+                                                <el-option :value="0" label="全部可选"></el-option>
+                                                <el-option :value="len" :label="item.list.length+'选'+len" v-for="len in item.list.length" v-if="item.list.length > 1"></el-option>
+                                            </el-select>
+                                        </div>
+                                    </div>
+                                    <div class="specs-tips">商品组名称中不可出现“任选N”“X选N”字样,当商品组的可选范围是“几选1”或“全部可选”时,不可配置重复选</div>
+                                    <div class="specs-body">
+                                        <div class="body-item" v-for="(its,ind) in item.list" :key="ind">
+                                            <div class="item-left">
+                                                <el-row :gutter="10">
+                                                    <el-col :span="12" class="mb10">
+                                                        <el-input placeholder="请输入单品名称 " v-model="its.name">
+                                                            <template #prepend>名称</template>
+                                                        </el-input>
+                                                    </el-col>
+                                                    <el-col :span="12" class="mb10">
+                                                        <el-input placeholder="单价" v-model="its.price" type="number">
+                                                            <template #prepend>单价</template>
+                                                            <template #append>元</template>
+                                                        </el-input>
+                                                    </el-col>
+                                                    <el-col :span="12" class="mb10">
+                                                        <el-input placeholder="请输入重量 " v-model="its.weight" type="number">
+                                                            <template #prepend>重量</template>
+                                                            <template #append>
+                                                                <el-select v-model="its.weight_unit">
+                                                                    <el-option value="kg" label="kg(千克)"></el-option>
+                                                                    <el-option value="g" label="g(克)"></el-option>
+                                                                    <el-option value="L" label="L(升)"></el-option>
+                                                                    <el-option value="ml" label="ml(毫升)"></el-option>
+                                                                    <el-option value="m" label="m(米)"></el-option>
+                                                                    <el-option value="m²" label="m²(平方米)"></el-option>
+                                                                    <el-option value="m³" label="m³(立方米)"></el-option>
+                                                                </el-select>
+                                                            </template>
+                                                        </el-input>
+                                                    </el-col>
+                                                    <el-col :span="12" class="mb10">
+                                                        <el-input placeholder="数量" v-model="its.number" type="number">
+                                                            <template #prepend>数量</template>
+                                                            <template #append>份</template>
+                                                        </el-input>
+                                                    </el-col>
+                                                </el-row>
+                                            </div>
+                                            <div class="item-dels">
+                                                <el-button type="danger" @click="removeItem(indx,ind)" circle icon="el-icon-delete" size="small"></el-button>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="specs-footer">
+                                         <el-button type="primary" size="small" @click="addItem(indx)">增加单品</el-button>
+                                        <el-button type="danger" size="small" @click="removeSpec(indx)">删除组</el-button>
+                                    </div>
+                                </div>
+                            </fieldset>
+                            <el-form-item label="多规格" prop="mult_sku">
+                                <el-radio-group v-model="formData.mult_sku">
+                                    <el-radio border :label="1">关闭</el-radio>
+                                    <el-radio border :label="2">开启</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <fieldset v-if="formData.mult_sku == 2">
+                                <legend><el-tag>规格明细</el-tag></legend>
+                                <el-button type="primary" @click="addSkuSpecs" v-if="skuSpecs.length<5">新增规格</el-button>
+                                <div class="sku-table">
+                                    <el-table :data="skuSpecs" border>
+                                        <el-table-column prop="image" label="规格图片" width="180">
+                                            <template #default="scope">
+                                                <sc-upload v-model="scope.row.image" title="规格图片" :cropper="true" :compress="1" :aspectRatio="1/1"></sc-upload>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column prop="sku_id" label="商品ID(必填)" width="220">
+                                            <template #default="scope">
+                                                <el-input v-model="scope.row.sku_id" placeholder="商品ID"></el-input>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column prop="name" label="名称(必填)" width="220">
+                                            <template #default="scope">
+                                                <el-input v-model="scope.row.name" maxlength="40" show-word-limit placeholder="SKU名称"></el-input>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column prop="line_price" label="划线价(必填)" width="160">
+                                            <template #default="scope">
+                                                <el-input v-model="scope.row.line_price" type="number" placeholder="划线价">
+                                                    <template #prepend>¥</template>
+                                                </el-input>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column prop="price" label="支付价(必填)" width="160">
+                                            <template #default="scope">
+                                                <el-input v-model="scope.row.price" type="number" placeholder="支付价">
+                                                    <template #prepend>¥</template>
+                                                </el-input>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column prop="custom_price" label="差价(必填)" width="160" v-if="formData.product_type == 11">
+                                            <template #default="scope">
+                                                <el-input v-model="scope.row.custom_price" type="number" placeholder="差价">
+                                                    <template #prepend>¥</template>
+                                                </el-input>
+                                            </template>
+                                        </el-table-column>
+                                        <el-table-column label="操作" align="left" fixed="right" width="120">
+                                            <template #default="scope">
+                                                <el-button type="danger" size="small" @click="removeItemSku(scope.$index)" icon="el-icon-delete">删除</el-button>
+                                                <el-button size="small" @click="itemSkuView(scope.$index,scope.row)">规格详情</el-button>
+                                            </template>
+                                        </el-table-column>
+                                    </el-table>
+                                </div>
+                            </fieldset>
+                            <el-form-item label="商品头图" prop="image_list">
+                                <sc-upload-multiple v-model="formData.image_list" :multiple="false" draggable :limit="10" tip="图片尺寸不超过5M,图片越小呈现的速度越快,建议分辨率不低于750*562px"></sc-upload-multiple>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-form-item label="辅助图" prop="detail_image_list">
+                                <sc-upload-multiple v-model="formData.detail_image_list" :multiple="false" draggable :limit="4" tip="辅助图上传1-4张,每张图片不得超过5M,建议分辨率不低于750*562px"></sc-upload-multiple>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-form-item label="环境图" prop="environment_image_list">
+                                <sc-upload-multiple v-model="formData.environment_image_list" :multiple="false" draggable :limit="10" tip="良好的环境也是用户的优先选择,最多可上传10张。每张图片不得超过5M,建议分辨率不低于750*562px"></sc-upload-multiple>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                        </el-card>
+                        <el-card shadow="never" header="售卖信息">
+                            <el-form-item label="投放渠道" prop="show_channel">
+                                <el-radio-group v-model="formData.show_channel">
+                                    <el-radio :label="1">不限制</el-radio>
+                                    <el-popover placement="top-start" trigger="hover" content="用户仅可在直播间开播时支付购买,售价及库存均仅在直播间渠道生效。用户无法通过收藏或分享的商品链接支付购买。如希望以此售价通过多渠道分享和售卖,投放渠道需选择“不限制”。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="2">
+                                                <template #default>
+                                                    <div class="radio-flex">仅直播间展示 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="用户仅可通过线下二维码等物料购买,商品不会在线上任何渠道展示和售卖。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="5">
+                                                <template #default>
+                                                    <div class="radio-flex">仅线下 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="新用户只可在新人频道购买,售价及库存仅在新人频道生效,用户无法通过收藏或分享的商品链接支付购买。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="7">
+                                                <template #default>
+                                                    <div class="radio-flex">仅新人频道 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="用户可通过线上所有渠道购买(除新人频道),但不可通过线下二维码物料购买。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="8">
+                                                <template #default>
+                                                    <div class="radio-flex">仅线上 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="用户仅可在免费试频道购买,免费价格及库存仅针对参与免费试活动条件的用户生效。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="18">
+                                                <template #default>
+                                                    <div class="radio-flex">仅免费试 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="用户仅可在「团购」页面看到和购买商品。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="22">
+                                                <template #default>
+                                                    <div class="radio-flex">仅团购商城 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="商品售卖日期内,用户仅在直播间和获客卡渠道可支付购买,售价及库存均仅在直播间和获客卡渠道生效。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="23">
+                                                <template #default>
+                                                    <div class="radio-flex">直播间+获客卡 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                    <el-popover placement="top-start" trigger="hover" content="该渠道商品不会在常规渠道售卖,需报名参加营销活动进行售卖。" :width="280">
+                                        <template #reference>
+                                            <el-radio :label="25">
+                                                <template #default>
+                                                    <div class="radio-flex">仅活动报名 <el-icon><el-icon-question-filled /></el-icon></div>
+                                                </template>
+                                            </el-radio>
+                                        </template>
+                                    </el-popover>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-form-item label="库存数量" prop="limit_use_rule">
+                                <el-radio-group v-model="formData.limit_use_rule">
+                                    <el-radio :label="2">不限制</el-radio>
+                                    <el-radio :label="1">限库存</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                                <div class="date-list" v-if="formData.limit_use_rule==1">
+                                    <el-form-item label="" prop="use_num_per_consume">
+                                        <el-input v-model="formData.use_num_per_consume">
+                                            <template #append>份</template>
+                                            <template #prepend>团购库存数量</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="商品售卖日期" prop="sold_start_times">
+                                <div style="width: 30%;">
+                                    <el-date-picker v-model="formData.sold_start_times" placeholder="请选择商品售卖日期" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" />
+                                </div>
+                                <div class="el-form-item-msg">顾客可以在这个时间内购买商品,超过这个日期,活动自动下线</div>
+                                <div class="radio-flex">
+                                    自动延期<el-switch active-text="开" inactive-text="关" inline-prompt v-model="formData.auto_renew" style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" :active-value="1" :inactive-value="0"/>
+                                    <span class="fs12">团购到期后自动延长30天(有效期同时延长),可随时关闭。</span>
+                                </div>
+                            </el-form-item>
+                        </el-card>
+                        <el-card shadow="never" header="交易规则">
+                            <el-form-item label="顾客可消费日期" prop="use_date_type">
+                                <el-radio-group v-model="formData.use_date_type">
+                                    <el-radio :label="1">指定天数</el-radio>
+                                    <el-radio :label="2">指定日期</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg" v-if="formData.use_date_type==1"></div>
+                                <div class="el-form-item-msg" v-if="formData.use_date_type==2">
+                                    可使用日期的结束时间必须晚于售卖日期的结束时间
+                                </div>
+                                <div class="date-list" v-if="formData.use_date_type==1">
+                                    <el-input v-model="formData.day_duration">
+                                        <template #append>天,购买当日默认可用</template>
+                                        <template #prepend>自购买次日起</template>
+                                    </el-input>
+                                </div>
+                                <div class="date-list" v-if="formData.use_date_type==2">
+                                    <el-date-picker v-model="formData.use_times" placeholder="请选择商品售卖日期" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" />
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="顾客信息设置" prop="customer_reserved_info">
+                                <el-radio-group v-model="formData.customer_reserved_info" disabled>
+                                    <el-radio :label="1">不需要</el-radio>
+                                    <el-radio :label="2">需要顾客手机号码</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                            </el-form-item>
+                            <el-form-item label="顾客不可消费日期" prop="can_no_use_date">
+                                <el-radio-group v-model="formData.can_no_use_date">
+                                    <el-radio :label="1">所有日期均可使用</el-radio>
+                                    <el-radio :label="2">部分日期不可用</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                                <template v-if="formData.can_no_use_date==2">
+                                    <div class="date-list">
+                                        <div class="date-type-item">
+                                            <div class="item-header"><el-checkbox v-model="formData.can_no_use_week" :value="1" label="每周几不可用" /></div>
+                                            <div class="item-body" style="width: 500px;" v-if="formData.can_no_use_week">
+                                                <el-form-item label="" prop="no_use_weeks">
+                                                    <el-select v-model="formData.no_use_weeks" multiple placeholder="请选择" style="width:100%">
+                                                        <el-option v-for="(item,index) in weeksData" :key="index" :label="item.name" :value="item.key"></el-option>
+                                                    </el-select>
+                                                </el-form-item>
+                                            </div>
+                                        </div>
+                                        <!-- <div class="date-type-item">
+                                            <div class="item-header"><el-checkbox v-model="formData.can_no_use_holiday" :value="1" label="节假日不可用" /></div>
+                                            <div class="item-body" style="width: 500px;" v-if="formData.can_no_use_holiday">
+                                                <el-form-item label="" prop="no_use_holidays">
+                                                    <el-select v-model="formData.no_use_holidays" multiple placeholder="请选择" style="width:100%">
+                                                        <el-option v-for="(item,index) in holiday" :key="index" :label="item.name" :value="item.key"></el-option>
+                                                    </el-select>
+                                                </el-form-item>
+                                            </div>
+                                        </div> -->
+                                        <div class="date-type-item">
+                                            <div class="item-header"><el-checkbox v-model="formData.can_no_use_day" :value="1" label="指定某天不可用" /></div>
+                                            <div class="item-body" style="width: 500px;" v-if="formData.can_no_use_day">
+                                                <el-form-item label="" prop="no_use_days">
+                                                    <el-date-picker
+                                                        v-model="formData.no_use_days"
+                                                        type="dates"
+                                                        style="width:100%"
+                                                        placeholder="请选择日期"
+                                                    />
+                                                </el-form-item>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </template>
+                            </el-form-item>
+                            
+                            
+                        </el-card>
+                        <el-card shadow="never" header="消费规则">
+                            <el-form-item label="使用规则">
+                                <div class="el-form-item-msg">
+                                    <el-button @click="addRule">添加规则</el-button>
+                                </div>
+                                <div class="date-list" style="margin-top: 10px;" v-if="notificationData.length > 0">
+                                    <div class="date-type-item flex" v-for="(item,index) in notificationData" :key="index">
+                                        <div class="left">
+                                            <el-input v-model="item.title" placeholder="请输入标题" />
+                                            <el-input v-model="item.content" placeholder="请输入规则内容" />
+                                        </div>
+                                        <div class="right">
+                                            <el-button type="danger" size="small" @click="removeRule(index)" circle icon="el-icon-delete"></el-button>
+                                        </div>
+                                    </div>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="限购规则" prop="limit_rule_type">
+                                <el-radio-group v-model="formData.limit_rule_type">
+                                    <el-radio :label="1">不限制购买</el-radio>
+                                    <el-radio :label="2">限制购买</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                                <div class="date-list" v-if="formData.limit_rule_type==2">
+                                    <el-input v-model="formData.limit_rule">
+                                        <template #append>份</template>
+                                        <template #prepend>限制每人最多购买</template>
+                                    </el-input>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="预约规则" prop="booking_type">
+                                <el-radio-group v-model="formData.booking_type">
+                                    <el-radio :label="1">无需预约</el-radio>
+                                    <el-radio :label="2">到店前需要预约</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                                <div class="date-list" v-if="formData.booking_type==2">
+                                    <el-input v-model="formData.booking_date">
+                                        <template #prepend>需提前</template>
+                                        <template #append>
+                                            <el-select v-model="formData.booking_unit" style="width: 80px;">
+                                                <el-option :value="1" label="天"></el-option>
+                                                <el-option :value="2" label="小时"></el-option>
+                                            </el-select>
+                                        </template>
+                                    </el-input>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="使用张数限制" prop="rec_person_type">
+                                <el-radio-group v-model="formData.rec_person_type">
+                                    <el-radio :label="1">不限制张数</el-radio>
+                                    <el-radio :label="2">限制张数</el-radio>
+                                </el-radio-group>
+                                <div class="el-form-item-msg"></div>
+                                <div class="date-list" v-if="formData.rec_person_type==2">
+                                    <el-input v-model="formData.rec_person_num_max">
+                                        <template #prepend>单次消费最多使用张数</template>
+                                        <template #append>张</template>
+                                    </el-input>
+                                </div>
+                            </el-form-item>
+                        </el-card>
+                        </template>
+                    </el-form>
+                </el-col>
+                <el-col :span="6">
+                    <el-card shadow="never" header="详情预览">
+                        <div class="sub-tips">该功能只做预览,实际效果以真机为准</div>
+                        <div class="preview-mobile">
+                            <div class="mobile-bannber">
+                                <el-carousel :interval="5000" arrow="always">
+                                    <el-carousel-item v-for="item in formData.image_list" :key="item">
+                                        <el-image :src="item.url"></el-image>
+                                    </el-carousel-item>
+                                </el-carousel>
+                            </div>
+                            <div class="mobile-info">
+                                <div class="info-price">
+                                    <span class="price">{{ formData.price?$TOOL.moneyFormat(formData.price):'¥0.00' }}</span>
+                                    <span class="line">{{ formData.line_price?$TOOL.moneyFormat(formData.line_price):'¥0.00' }}</span>
+                                    <span class="dis">{{ $TOOL.disFormat(formData.price,formData.line_price) }}折</span>
+                                </div>
+                                <div class="info-title">{{ formData.product_name?formData.product_name:'演示商品标题' }}</div>
+                                <div class="sku-list" v-if="skuSpecs.length > 0">
+                                    <div class="sku-title">规格<br>选择</div>
+                                    <div class="sku-list-body">
+                                        <div class="sku-item" v-for="(item,indx) in skuSpecs" :key="indx">{{item.name}}</div>
+                                    </div>
+                                </div>
+                                <div class="item-tag">
+                                    <div class="tag-li"><el-icon color="#f00" size="14"><el-icon-circle-check /></el-icon>过期退</div>
+                                    <div class="tag-li"><el-icon color="#f00" size="14"><el-icon-circle-check /></el-icon>随时退</div>
+                                </div>
+                            </div>
+                            <div class="mobile-group">
+                                <div class="group-title">团购套餐</div>
+                                <div class="group-body" v-if="specs.length > 0" v-for="(item,indx) in specs" :key="indx">
+                                    <div class="body-title">
+                                        {{item.name}}
+                                        <span v-if="item.num == 0">全部可选</span>
+                                        <span v-else>{{item.list.length}}选{{item.num}}</span>
+                                    </div>
+                                    <div class="body-item">
+                                        <div class="body-item-li" v-for="(its,idx) in item.list" :key="idx">
+                                            {{its.name}}
+                                            <div class="item-right">
+                                                <span>({{its.number}}份)</span>
+                                                <span>{{$TOOL.moneyFormat(its.price)}}</span>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="mobile-group">
+                                <div class="group-title">购买须知</div>
+                                <div class="group-mix">
+                                    <div class="mix-title">
+                                        <el-icon size="14" color="#000"><el-icon-suitcase /></el-icon>有效期
+                                    </div>
+                                    <div class="mix-item" v-if="formData.use_date_type==1">
+                                        购买后 <span>{{ formData.day_duration }}</span> 天有效
+                                    </div>
+                                    <div class="mix-item" v-if="formData.use_date_type==2">
+                                        <span v-if="formData.use_times">
+                                        {{ $TOOL.dateFormat(formData.use_times[0],'yyyy-MM-dd') }}至{{ $TOOL.dateFormat(formData.use_times[1],'yyyy-MM-dd') }}
+                                        </span>
+                                    </div>
+                                </div>
+                                <div class="group-mix">
+                                    <div class="mix-title">
+                                        <el-icon size="14" color="#000"><el-icon-clock /></el-icon>可用时间
+                                    </div>
+                                    <div class="mix-item" v-if="formData.can_no_use_date==1">
+                                        商家营业时间可用
+                                    </div>
+                                </div>
+                                <div class="group-mix">
+                                    <div class="mix-title">
+                                        <el-icon size="14" color="#000"><el-icon-alarm-clock /></el-icon>预约规则
+                                    </div>
+                                    <div class="mix-item" v-if="formData.booking_type==1">
+                                        无需预约,高峰期可能需要排队
+                                    </div>
+                                    <div class="mix-item" v-if="formData.booking_type==2">
+                                        需要提前<span>{{ formData.booking_date }}</span>{{ formData.booking_unit==1?'天':'小时' }}预约
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </el-card>
+                </el-col>
+            </el-row>
+        </el-main>
+        <el-footer style="text-align: center;">
+            <el-button @click="reback" size="large">取 消</el-button>
+            <el-button size="large" type="primary" :loading="isSaveing" @click="submit()">提交审核</el-button>
+        </el-footer>
+    </el-container>
+    <skuView ref="skuView" @success="skuResp"></skuView>
+</template>
+
+<script>
+import dayjs from 'dayjs';
+import skuView from './components/sku'
+export default {
+    components:{
+        skuView
+    },
+    data(){
+        return {
+            isSaveing:false,
+            showNext:true,
+            formData:{
+                settle_type:1,
+                show_channel:1,
+                limit_use_rule:1,
+                auto_renew:true,
+                use_date_type:1,
+                day_duration:30,
+                can_no_use_date:1,
+                code_source_type:1,
+                limit_rule_type:1,
+                limit_rule:1,
+                booking_date:1,
+                booking_type:1,
+                booking_unit:1,
+                rec_person_type:1,
+                rec_person_num_max:1,
+                image_list:[],
+                detail_image_list:[],
+                environment_image_list:[],
+                mult_sku:1,
+                stock_type:1
+            },
+            holiday:[{'key':1,"name":"元旦"},{'key':2,"name":"春节"},{'key':3,"name":"清明"},{'key':4,"name":"劳动节"},{'key':5,"name":"端午节"},{'key':6,"name":"中秋节"},{'key':7,"name":"国庆节"},{'key':8,"name":"情人节"},{'key':9,"name":"圣诞节"},{'key':10,"name":"元宵节"},{'key':11,"name":"520"},{'key':12,"name":"儿童节"},{'key':13,"name":"七夕节"},{'key':14,"name":"二月二"},{'key':15,"name":"母亲节"},{'key':16,"name":"父亲节"},{'key':17,"name":"教师节"}],
+            weeksData:[{'key':1,"name":"星期一"},{'key':2,"name":"星期二"},{'key':3,"name":"星期三"},{'key':4,"name":"星期四"},{'key':5,"name":"星期五"},{'key':6,"name":"星期六"},{'key':7,"name":"星期天"},],
+            notificationData:[],
+            specs:[{"name":"","num":0,"list":[ {"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1} ]}],
+            skuSpecs:[],
+            channelLoad:false,
+            rules:{
+                custom_price: [
+                    {required: true, message: '请输入'}
+                ],
+                no_use_weeks: [
+                    {required: true, message: '请选择'}
+                ],
+                no_use_holidays: [
+                    {required: true, message: '请选择'}
+                ],
+                no_use_days: [
+                    {required: true, message: '请选择'}
+                ],
+                customer_reserved_info: [
+                    {required: true, message: '请选择'}
+                ],
+                line_price: [
+                    {required: true, message: '请输入'}
+                ],
+                price: [
+                    {required: true, message: '请输入'}
+                ],
+                image_list: [
+                    {required: true, message: '请上传'}
+                ],
+                rec_person_type: [
+                    {required: true, message: '请选择'}
+                ],
+                code_source_type: [
+                    {required: true, message: '请选择'}
+                ],
+                can_no_use_date: [
+                    {required: true, message: '请选择'}
+                ],
+                use_date_type: [
+                    {required: true, message: '请选择'}
+                ],
+                product_name: [
+                    {required: true, message: '请输入'}
+                ],
+                use_num_per_consume: [
+                    {required: true, message: '请输入'}
+                ],
+                limit_use_rule: [
+                    {required: true, message: '请选择'}
+                ],
+                sold_start_times: [
+                    {required: true, message: '请选择'}
+                ],
+                show_channel: [
+                    {required: true, message: '请选择'}
+                ],
+                settle_type: [
+                    {required: true, message: '请选择'}
+                ],
+                category: [
+                    {required: true, message: '请选择'}
+                ],
+                product_type: [
+                    {required: true, message: '请选择'}
+                ],
+                stock_type: [
+                    {required: true, message: '请选择'}
+                ],
+            },
+            deptsProps:{
+                value: "category_id",
+                label: "name"
+            },
+            typeData:null,
+            categoryData:[]
+        }
+    },
+    created(){
+        this.getData()
+        var id = this.$route.query.id;
+        var product_id = this.$route.query.product_id;
+        this.getDetail(id,product_id);
+        // this.formData.sold_start_time = this.formattedCurrentDate();
+    },
+    methods: {
+        addRule(){
+            this.notificationData.push({"title":"","content":""});
+        },
+        removeRule(index){
+            if (this.notificationData.length <= 1) {
+                return this.$message.error("至少保留一条规则")
+            }
+            this.notificationData.splice(index,1)
+        },
+        async getDetail(id,product_id){
+            var resp = await this.$API.merGoods.detail.get({"id":id,"product_id":product_id});
+            if (resp.code == 0) {
+                this.$message.error(resp.msg);
+                setTimeout(function(){
+                    this.$router.go(-1)
+                },1500)
+            }
+            this.formData = resp.data;
+            this.specs = resp.data.specs;
+            this.skuSpecs = resp.data.skuSpecs;
+            this.notificationData = resp.data.notification
+            
+            var typeData = this.$TOOL.findNodeById(this.categoryData,parseInt(this.formData.category_id));
+            if (!typeData) return this.$message.error("获取商品类型失败")
+            this.typeData = typeData.types;
+            this.showNext = true;
+        },
+        skuResp(data){
+            this.skuSpecs[data.index] = data.data;
+        },
+        itemSkuView(index,data){
+            this.$nextTick(() => {
+                this.$refs.skuView.open("edit").setData(index,data)
+            })
+        },
+        addSkuSpecs(){
+            if(!this.formData.price) return this.$message.error("请先设置顾客实际需支付金额");
+            this.skuSpecs.push({"image":"","sku_id":this.generate(),"name":"","line_price":1,"price":this.formData.price,"is_default":false,"specs":[]});
+        },
+        removeItemSku(index){
+            this.skuSpecs.splice(index,1)
+        },
+        addSpecs(){
+            if (this.specs.length >= 5) {
+                return this.$message.error("最多只能添加三组规格")
+            }
+            this.specs.push({"name":"","num":0,"list":[ {"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1} ]});
+        },
+        addItem(index){
+            if (this.specs[index].list.length >= 20) {
+                return this.$message.error("最多只能添加20个")
+            }
+            this.specs[index].list.push({"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1})
+        },
+        removeSpec(index){
+            this.specs.splice(index,1)
+        },
+        removeItem(index,sub){
+            this.specs[index].list.splice(sub,1)
+        },
+        generate() {
+            let timestamp = Date.now();
+            if (timestamp === this.lastTimestamp) {
+                this.sequence++;
+            } else {
+                this.sequence = 0;
+                this.lastTimestamp = timestamp;
+            }
+            const randomPart = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
+            const timestampPart = timestamp.toString().slice(-6);   // 取时间戳后6位
+            const seqPart = this.sequence.toString().padStart(2, '0'); // 序列号占2位(0-99)
+            let base = timestampPart + seqPart + randomPart; // 6+2+4=12位
+            const remainingLength = 18 - base.length;
+            const extraRandom = Math.floor(Math.random() * Math.pow(10, remainingLength)).toString().padStart(remainingLength, '0');
+            return base + extraRandom; // 最终18位字符串
+        },
+        formattedCurrentDate() {
+            const now = dayjs();
+            const currentDate = now.format('YYYY-MM-DD HH:mm:ss');
+            const nextYearDate = now.add(1, 'year').format('YYYY-MM-DD HH:mm:ss');
+            return [currentDate,nextYearDate];
+        },
+        async getTemplate(){
+            const nodes = this.$refs.cascaderRef.getCheckedNodes()
+            var typeData = this.$TOOL.findNodeById(this.categoryData,nodes[0].value);
+            if (!typeData) return this.$message.error("获取商品类型失败")
+            this.typeData = typeData.types;
+            this.showNext = true;
+            // var { formData, $message } = this;
+            // if (formData.product_type && formData.category) {
+            //     // var resp = await this.$API.merGoods.template.post({"product_type":formData.product_type,"category":formData.category});
+            //     this.showNext = true;
+            //     return ;
+            // }
+        },
+        async getData(){
+            this.channelLoad = true;
+            var resp = await this.$API.merGoods.category.get();
+            this.channelLoad = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg)
+            }
+            this.categoryData = resp.data;
+            // this.getCate()
+        },
+        async getCate(){
+            var resp = await this.$API.merGoods.type.get();
+            this.channelLoad = false;
+            if (resp.code == 0) {
+                return this.$message.error(resp.msg)
+            }
+            this.typeData = resp.data;
+        },
+        reback(){
+            this.$confirm(`确定要退出添加商品吗?`, '提示', {
+                type: 'warning'
+            }).then(() => {
+                this.$router.go(-1)
+            }).catch(() => {
+
+            })
+        },
+        async submit(){
+            var { formData, $message } = this;
+            var validate = await this.$refs.dialogForm.validate().catch(()=>{});
+            if(!validate){ return false }
+            if (this.notificationData.length == 0) {
+                return this.$message.error("使用规则至少需要一组以上");
+            }
+            formData.notification = this.notificationData;
+            formData.specs = this.specs;
+            formData.skuSpecs = this.skuSpecs;
+            if (formData.sold_start_times) {
+                var sold_start_time = formData.sold_start_times;
+                formData.sold_start_time = this.$TOOL.dateFormat(sold_start_time[0],"yyyy-MM-dd")
+                formData.sold_end_time = this.$TOOL.dateFormat(sold_start_time[1],"yyyy-MM-dd")
+            }
+            if (formData.use_times) {
+                var use_time = formData.use_times;
+                formData.use_time_start = this.$TOOL.dateFormat(use_time[0],"yyyy-MM-dd")
+                formData.use_time_end = this.$TOOL.dateFormat(use_time[1],"yyyy-MM-dd")
+            }
+            this.isSaveing = true;
+            var resp = await this.$API.merGoods.save.post(formData);
+            this.isSaveing = false;
+            if (resp.code == 0) {
+                return $message.error(resp.msg)
+            }
+            $message.success(resp.msg)
+            this.$router.go(-1)
+        }
+    }
+}
+</script>
+
+
+<style scoped>
+.group-mix .mix-title{display: flex;align-items: center;line-height: 32px;font-weight: bold;font-size: 12px;gap: 5px;}
+.group-mix .mix-item{padding-left: 10px;position: relative;line-height: 32px;margin-left: 10px;}
+.group-mix .mix-item span{color: orange;padding: 0 5px;}
+.group-mix .mix-item::after{position: absolute;top: 0;width: 5px;height: 5px;background-color: #000;border-radius: 5px;content: "";left: 0;top: 38%;}
+.mobile-group{background-color: #fff;margin-top: 10px;padding: 10px;}
+.mobile-group .group-title{font-size: 14px;font-weight: bold;color: #333;line-height: 36px;}
+.mobile-group .body-title{display: flex;align-items: center;line-height: 32px;font-size: 14px;color: #333;font-weight: bold;gap: 8px;}
+.mobile-group .body-title span{font-size: 12px;font-weight: normal;color: #666;}
+.mobile-group .body-item-li{display: flex;align-items: center;justify-content: space-between;line-height: 32px;font-size: 12px;color: #333;font-weight: bold;}
+.mobile-group .body-item-li .item-right{display: flex;align-items: center;gap: 10px;}
+
+
+.date-list{background-color: var(--el-fill-color-light);padding: 10px;border-radius: 2px;min-width: 500px;}
+.date-type-item{margin-bottom: 15px;}
+.date-type-item.flex{display: flex;align-items: center;gap: 10px;justify-content: space-between;}
+.date-type-item.flex .left{flex: 1;}
+
+.mobile-bannber{background-color: #f8f8f8;}
+.mobile-info{padding: 10px;background-color: #fff;}
+.mobile-info .info-title{font-size: 14px;font-weight: bold;line-height: 36px;}
+.mobile-info .info-price{display: flex;align-items: flex-end;gap: 8px;}
+.mobile-info .info-price .price{color: #f00;font-size: 22px;font-weight: bold;}
+.mobile-info .info-price .line{color: #666;font-size: 12px;text-decoration:line-through;}
+.mobile-info .info-price .dis{background-color: rgb(255, 234, 234);;color: rgb(255, 68, 68);;padding: 5px;border-radius: 2px;}
+.mobile-info .item-tag{display: flex;align-items: center;gap: 10px;font-size: 12px;}
+.mobile-info .item-tag .tag-li{display: flex;align-items: center;gap: 5px;}
+.mobile-info .sku-list{display: flex;align-items: center;margin: 10px 0;}
+.mobile-info .sku-list .sku-title{color: #999090;font-size: 12px;}
+.mobile-info .sku-list .sku-list-body{display: flex;align-items: center;margin-left: 8px;flex: 1;overflow: hidden;overflow-x: auto;gap: 8px;}
+.mobile-info .sku-list .sku-list-body .sku-item{background-color: #f6fafd;padding: 8px 16px;border-radius: 8px;text-wrap: nowrap;}
+
+.preview-mobile{margin-top: 10px;box-shadow: 0 20px 30px 0 rgb(63 63 65 / 6%);border-radius: 10px;border: 1px solid #f8f8f8;box-sizing: border-box;background-color: #f8f8f8;}
+.radio-flex{display: flex;align-items: center;gap: 5px;}
+.fs12{color: #999;font-size: 12px;}
+
+.specs{margin-top: 15px;background-color: #f8f8f8;}
+.specs-header{
+    display: flex;
+    background-color: #ddd;
+    padding: 10px;
+}
+.specs-tips{
+    padding: 0 10px 10px 10px;
+    background-color: #ddd;
+}
+.specs-header .specs-left{
+    display: flex;
+    align-items: center;
+    flex: 1;
+    gap: 10px;
+}
+.specs-header .specs-right{
+    display: flex;
+    margin-left: auto;
+    margin-right: 0;
+}
+.specs-body{display: flex;align-items: center;gap: 10px;padding: 10px;flex-direction: row;flex-wrap: wrap;}
+.specs-body .body-item{padding: 5px;display: flex;align-items: center;}
+.specs-body .body-item .item-dels{margin-left: 10px;}
+.item-img{margin-bottom: 5px;}
+.mb10{margin-bottom: 10px;}
+.specs-footer{background-color: #ddd;padding: 10px;}
+.sku-table{margin-top: 10px;}
+.el-upload__tip,
+.el-upload-list__item,
+.el-dialog__wrapper {
+    z-index: 9999 !important;
+}
+</style>

+ 7 - 3
src/views/manage/setting/basic/index.vue

@@ -16,8 +16,9 @@
                             <el-form-item label="系统Logo" prop="logo">
                             <el-form-item label="系统Logo" prop="logo">
                                 <sc-upload v-model="sys.logo"></sc-upload>
                                 <sc-upload v-model="sys.logo"></sc-upload>
                             </el-form-item>
                             </el-form-item>
-                            <el-form-item label="营业纸张" prop="license">
+                            <el-form-item label="营业执照" prop="license">
                                 <sc-upload v-model="sys.license"></sc-upload>
                                 <sc-upload v-model="sys.license"></sc-upload>
+                                <div class="el-form-item-msg">小程序端资质展示使用</div>
                             </el-form-item>
                             </el-form-item>
                             <el-form-item label="备案号" prop="miitbeian" class="label-item">
                             <el-form-item label="备案号" prop="miitbeian" class="label-item">
                                 <el-input v-model="sys.miitbeian" placeholder="请输入" clearable />
                                 <el-input v-model="sys.miitbeian" placeholder="请输入" clearable />
@@ -128,7 +129,7 @@ export default {
     },
     },
     data(){
     data(){
         return {
         return {
-            activeName:"wechat",
+            activeName:"service",
             isSaveing: false,
             isSaveing: false,
             sys: {},
             sys: {},
             smsRegion:[],
             smsRegion:[],
@@ -182,7 +183,10 @@ export default {
                 ],
                 ],
                 copyright: [
                 copyright: [
                     { required: true, message: '请输入' }
                     { required: true, message: '请输入' }
-                ]
+                ],
+                license: [
+                    { required: true, message: '请上传' }
+                ],
             },
             },
             isLoading:false
             isLoading:false
         }
         }

+ 8 - 1
src/views/merchant/finance/index/components/form.vue

@@ -12,6 +12,9 @@
                 </div>
                 </div>
             </div>
             </div>
             <el-main>
             <el-main>
+                <div class="mb10" v-if="formData.status && formData.status == 2">
+                    <el-alert title="驳回原因" :description="formData.remark" :show-icon="false" type="error"></el-alert>
+                </div>
                 <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
                 <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
                     <fieldset>
                     <fieldset>
                         <legend><el-button>商户主体信息</el-button></legend>
                         <legend><el-button>商户主体信息</el-button></legend>
@@ -236,4 +239,8 @@ export default {
         }
         }
     }
     }
 }
 }
-</script>
+</script>
+
+<style>
+.mb10{margin-bottom: 10px;}
+</style>