form.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. <template>
  2. <el-drawer v-model="visible" title="在线客服" size="800px" destroy-on-close :close-on-click-modal="false" :with-header="false">
  3. <el-container class="flex-column">
  4. <div class="drawer-detail-main">
  5. <div class="drawer-detail-header">
  6. <div class="drawer-detail-header-body">
  7. <div class="drawer-detail-header-left">{{titleMap[mode]}}</div>
  8. <div class="drawer-detail-header-left">
  9. <el-button type="default" icon="el-icon-close" @click="visible=false"></el-button>
  10. </div>
  11. </div>
  12. </div>
  13. </div>
  14. <el-main>
  15. <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
  16. <el-form-item label="计划名称" prop="plan_name">
  17. <el-input v-model="formData.plan_name" clearable placeholder="请输入"></el-input>
  18. <div class="el-form-item-msg"></div>
  19. </el-form-item>
  20. <el-form-item label="联系电话" prop="merchant_phone">
  21. <el-input v-model="formData.merchant_phone" clearable placeholder="请输入"></el-input>
  22. <div class="el-form-item-msg">必须是真实可用的手机号码,否则计划可能会不通过审核</div>
  23. </el-form-item>
  24. <el-form-item label="推广团购商品">
  25. <el-button type="default" @click="addGoods" v-if="goodsData.length<50">添加团购商品({{ goodsData.length }}/50</el-button>
  26. <el-button type="default" @click="quickGoods" v-if="goodsData.length > 0">一键设置佣金</el-button>
  27. <div class="goods-live" v-if="goodsData.length>0">
  28. <scTable ref="starTable" :data="goodsData" row-key="id" height="300" hidePagination hideDo style="width: 750px;">
  29. <el-table-column label="商品信息" width="340" prop="name" fixed="left">
  30. <template #default="scope">
  31. <div class="goods-img">
  32. <div class="img">
  33. <el-image
  34. style="width: 54px; height: 54px"
  35. :src="scope.row.image_list[0].url"
  36. :zoom-rate="1.2"
  37. :max-scale="7"
  38. :min-scale="0.2"
  39. :preview-src-list="[scope.row.image_list[0].url]"
  40. preview-teleported
  41. z-index="999"
  42. fit="cover"></el-image>
  43. </div>
  44. <div class="name">
  45. <span>{{ scope.row.product_name }}</span>
  46. <span class="dec">商品编码:{{ scope.row.product_id }}</span>
  47. </div>
  48. </div>
  49. </template>
  50. </el-table-column>
  51. <el-table-column label="佣金比例" prop="types" width="150">
  52. <template #default="scope">
  53. <el-input v-model="scope.row.rate" @input="setRate(scope.$index)" @focus="setRate(scope.$index)" placeholder="0%-29%">
  54. <template #suffix>%</template>
  55. </el-input>
  56. <div class="el-form-item-msg">预估每单佣金 {{ scope.row.rate_money }}</div>
  57. </template>
  58. </el-table-column>
  59. <el-table-column label="商品类型" prop="types" width="100"></el-table-column>
  60. <el-table-column label="价格" width="200" prop="id">
  61. <template #default="scope">
  62. <div class="price">{{ $TOOL.moneyFormat(scope.row.price) }}</div>
  63. <div class="goods-price">
  64. <div class="del">{{ $TOOL.moneyFormat(scope.row.line_price) }}</div>
  65. <span>{{ $TOOL.disFormat(scope.row.price,scope.row.line_price) }}折</span></div>
  66. </template>
  67. </el-table-column>
  68. <el-table-column label="剩余库存" prop="category_id" width="120">
  69. <template #default="scope">
  70. <span v-if="scope.row.limit_use_rule==1">{{ scope.row.use_num_per_consume }}</span>
  71. <span v-else>不限</span>
  72. </template>
  73. </el-table-column>
  74. <el-table-column label="状态" prop="enable" width="120" align="center">
  75. <template #default="scope">
  76. <div class="status-success" v-if="scope.row.status==1"><sc-status-indicator type="success"></sc-status-indicator> 正常</div>
  77. <div class="status-danger" v-if="scope.row.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 禁用</div>
  78. <div class="status-danger" v-if="scope.row.status==0"><sc-status-indicator type="danger"></sc-status-indicator> 审核中</div>
  79. </template>
  80. </el-table-column>
  81. <el-table-column label="操作" width="100" align="left" fixed="right">
  82. <template #default="scope">
  83. <el-button-group>
  84. <el-button type="danger" text size="small" @click="removeGoods(scope.$index)">删除</el-button>
  85. </el-button-group>
  86. </template>
  87. </el-table-column>
  88. </scTable>
  89. </div>
  90. </el-form-item>
  91. <el-form-item label="指定带货达人">
  92. <el-button type="default" @click="addStar" v-if="starData.length<200">添加达人({{ starData.length }}/200)</el-button>
  93. <div class="goods-live" v-if="starData.length>0">
  94. <scTable ref="starTable" :data="starData" row-key="id" height="300" hidePagination hideDo style="width: 750px;">
  95. <el-table-column label="达人" width="340" prop="name" fixed="left">
  96. <template #default="scope">
  97. <div class="goods-img">
  98. <div class="img">
  99. <el-image
  100. style="width: 54px; height: 54px"
  101. :src="scope.row.avatar_url"
  102. :zoom-rate="1.2"
  103. :max-scale="7"
  104. :min-scale="0.2"
  105. :preview-src-list="[scope.row.avatar_url]"
  106. preview-teleported
  107. z-index="999"
  108. fit="cover"></el-image>
  109. </div>
  110. <div class="name">
  111. <span>{{ scope.row.show_nickname }}</span>
  112. <span class="dec">抖音号:{{ scope.row.unique_id }}</span>
  113. </div>
  114. </div>
  115. </template>
  116. </el-table-column>
  117. <el-table-column label="粉丝数" width="200" prop="id">
  118. <template #default="scope">
  119. <div class="price">{{ scope.row.fans_count }}</div>
  120. <div class="goods-price">
  121. <span v-for="value in scope.row.fans_tag_list">{{ value }}</span></div>
  122. </template>
  123. </el-table-column>
  124. <el-table-column label="本地粉丝数" width="120" prop="id">
  125. <template #default="scope">
  126. <div class="price">{{ scope.row.local_fans_count }}</div>
  127. </template>
  128. </el-table-column>
  129. <el-table-column label="视频带货力" prop="category_id" width="120">
  130. <template #default="scope">
  131. <span v-if="scope.row.talent_item_level_display">{{ scope.row.talent_item_level_display }}</span>
  132. <span v-else>-</span>
  133. </template>
  134. </el-table-column>
  135. <el-table-column label="直播带货力" prop="talent_live_level_display" width="120">
  136. <template #default="scope">
  137. <span v-if="scope.row.talent_live_level_display">{{ scope.row.talent_live_level_display }}</span>
  138. <span v-else>-</span>
  139. </template>
  140. </el-table-column>
  141. <el-table-column label="内容力" prop="category_id" width="120">
  142. <template #default="scope">
  143. <span v-if="scope.row.content_level_display">{{ scope.row.content_level_display }}</span>
  144. <span v-else>-</span>
  145. </template>
  146. </el-table-column>
  147. <el-table-column label="信用分" prop="category_id" width="120">
  148. <template #default="scope">
  149. <span v-if="scope.row.credit_score_display">{{ scope.row.credit_score_display }}</span>
  150. <span v-else>-</span>
  151. </template>
  152. </el-table-column>
  153. <el-table-column label="视频榜" prop="category_id" width="120">
  154. <template #default="scope">
  155. <span v-if="scope.row.rank_display">{{ scope.row.city_name }} 第{{ scope.row.rank_display }}名</span>
  156. <span v-else>-</span>
  157. </template>
  158. </el-table-column>
  159. <el-table-column label="状态" prop="enable" width="120" align="center">
  160. <template #default="scope">
  161. <div class="status-success" v-if="scope.row.status==1"><sc-status-indicator type="success"></sc-status-indicator> 正常</div>
  162. <div class="status-danger" v-if="scope.row.status==2"><sc-status-indicator type="danger"></sc-status-indicator> 禁用</div>
  163. </template>
  164. </el-table-column>
  165. <el-table-column label="创建时间" prop="create_at" width="180"></el-table-column>
  166. <el-table-column label="操作" width="100" align="left" fixed="right">
  167. <template #default="scope">
  168. <el-button-group>
  169. <el-button type="danger" text size="small" @click="removeStar(scope.$index)">删除</el-button>
  170. </el-button-group>
  171. </template>
  172. </el-table-column>
  173. </scTable>
  174. </div>
  175. </el-form-item>
  176. <!-- <el-form-item label="状态" prop="status">
  177. <el-radio-group v-model="formData.status">
  178. <el-radio-button :label="1">正常</el-radio-button>
  179. <el-radio-button :label="2">禁用</el-radio-button>
  180. </el-radio-group>
  181. <div class="el-form-item-msg">禁用后的达人不可绑定直播计划</div>
  182. </el-form-item> -->
  183. </el-form>
  184. </el-main>
  185. <el-footer>
  186. <el-button @click="visible=false" size="large">取 消</el-button>
  187. <el-button v-if="mode!='show'" size="large" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
  188. </el-footer>
  189. </el-container>
  190. </el-drawer>
  191. <starMain ref="starMain" :multiple="true" @success="handleStar"></starMain>
  192. <goodsMain ref="goodsMain" :multiple="true" @success="handleGoods"></goodsMain>
  193. <el-dialog title="一键设置佣金" v-model="quickData.visible" :width="460" append-to-body destroy-on-close :close-on-click-modal="false">
  194. <el-form ref="quickForm" :model="quickData.formData" :rules="quickData.rules" label-width="100px" label-position="top">
  195. <el-form-item label="输入后商品将设置相同佣金" prop="rate">
  196. <el-input v-model="quickData.formData.rate" clearable placeholder="0%-29%">
  197. <template #suffix>%</template>
  198. </el-input>
  199. <div class="el-form-item-msg">佣金比例请设置在0%-29%之间</div>
  200. </el-form-item>
  201. </el-form>
  202. <template #footer>
  203. <el-button @click="quickData.visible=false" size="large">取 消</el-button>
  204. <el-button size="large" type="primary" :loading="quickData.isSaveing" @click="submitRate()">保 存</el-button>
  205. </template>
  206. </el-dialog>
  207. </template>
  208. <script>
  209. export default {
  210. data(){
  211. return {
  212. quickData:{
  213. visible:false,
  214. rate:null,
  215. isSaveing:false,
  216. formData:{
  217. rate:null
  218. },
  219. rules:{
  220. rate: [
  221. {required: true, message: '请输入'}
  222. ],
  223. }
  224. },
  225. goodsData:[],
  226. starData:[],
  227. loading: false,
  228. isSaveing: false,
  229. mode:"add",
  230. titleMap:{
  231. add:"创建直播计划",
  232. edit:"编辑直播计划"
  233. },
  234. visible:false,
  235. formData:{
  236. status:1
  237. },
  238. rules:{
  239. status: [
  240. {required: true, message: '请选择'}
  241. ],
  242. plan_name: [
  243. {required: true, message: '请输入'}
  244. ],
  245. merchant_phone: [
  246. {required: true, message: '请输入'}
  247. ]
  248. }
  249. }
  250. },
  251. methods:{
  252. open(mode = 'add'){
  253. this.mode = mode;
  254. this.visible = true;
  255. return this
  256. },
  257. //表单注入数据
  258. setData(data){
  259. this.formData = JSON.parse(JSON.stringify(data));
  260. },
  261. setRate(index){
  262. const goods = this.goodsData[index];
  263. if (parseFloat(goods.rate) > 29) {
  264. this.goodsData[index].rate = 0;
  265. this.goodsData[index].rate_money = 0;
  266. return ;
  267. }
  268. const rateMoney = this.$TOOL.moneyFormat(parseFloat(goods.rate) * goods.price / 100);
  269. this.goodsData[index].rate_money = rateMoney;
  270. },
  271. quickGoods(){
  272. this.quickData.visible = true;
  273. },
  274. addGoods(){
  275. this.$nextTick(() => {
  276. this.$refs.goodsMain.open("add")
  277. })
  278. },
  279. removeGoods(index){
  280. this.goodsData.splice(index,1);
  281. },
  282. addStar(){
  283. this.$nextTick(() => {
  284. this.$refs.starMain.open("add")
  285. })
  286. },
  287. removeStar(index){
  288. this.starData.splice(index,1);
  289. },
  290. handleStar(data){
  291. var newData = [];
  292. data.forEach((value)=>{
  293. const has = this.starData.some(item => item['id'] === value['id'])
  294. if (!has) newData.push(value)
  295. })
  296. if (newData.length > 0) {
  297. this.starData = this.starData.concat(newData);
  298. }
  299. },
  300. handleGoods(data){
  301. var newData = [];
  302. data.forEach((value)=>{
  303. value.rate = 0;
  304. value.rate_money = 0;
  305. const has = this.goodsData.some(item => item['id'] === value['id'])
  306. if (!has) newData.push(value)
  307. })
  308. if (newData.length > 0) {
  309. this.goodsData = this.goodsData.concat(newData);
  310. }
  311. },
  312. async submitRate(){
  313. var validate = await this.$refs.quickForm.validate().catch(()=>{});
  314. if(!validate){ return false }
  315. if (parseFloat(this.quickData.formData.rate) > 29) {
  316. this.quickData.formData.rate = 0;
  317. return ;
  318. }
  319. this.quickData.isSaveing = true;
  320. var goodsData = this.goodsData;
  321. goodsData.forEach((item) =>{
  322. const rateMoney = this.$TOOL.moneyFormat(parseFloat(this.quickData.formData.rate) * item.price / 100);
  323. item.rate_money = rateMoney;
  324. item.rate = this.quickData.formData.rate;
  325. })
  326. this.goodsData = goodsData;
  327. this.quickData.isSaveing = false;
  328. this.quickData.visible = false;
  329. },
  330. async submit(){
  331. var validate = await this.$refs.dialogForm.validate().catch(()=>{});
  332. if(!validate){ return false }
  333. if (this.goodsData.length == 0) return this.$message.error("请添加团购商品")
  334. if (this.starData.length == 0) return this.$message.error("请添加达人")
  335. this.isSaveing = true;
  336. let submitData = JSON.parse(JSON.stringify(this.formData));
  337. submitData.goods = JSON.stringify(this.goodsData);
  338. submitData.star = JSON.stringify(this.starData);
  339. var resp = await this.$API.merPlan.save.post(submitData);
  340. this.isSaveing = false;
  341. if (resp.code == 0) {
  342. return this.$message.error(resp.msg);
  343. }
  344. this.$message.success(resp.msg);
  345. this.visible = false;
  346. this.formData = {};
  347. this.$emit("success");
  348. }
  349. }
  350. }
  351. </script>
  352. <style>
  353. .text-center{text-align: center;}
  354. .goods-live{width: 100%;margin-top: 10px;}
  355. </style>