add.vue 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. <template>
  2. <el-container>
  3. <el-main>
  4. <el-row :gutter="20">
  5. <el-col :span="18">
  6. <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
  7. <el-card shadow="never" header="商品类型">
  8. <el-form-item label="商品品类" prop="category">
  9. <el-cascader v-model="formData.category" :options="categoryData" :props="deptsProps" @change="getTemplate" clearable style="width: 50%;" />
  10. <div class="el-form-item-msg"></div>
  11. </el-form-item>
  12. <el-form-item label="商品类型" prop="product_type" @change="getTemplate" v-loading="channelLoad">
  13. <el-radio-group v-model="formData.product_type">
  14. <el-radio border :label="item.key" v-for="(item,index) in typeData" :key="index">{{item.name}}</el-radio>
  15. </el-radio-group>
  16. <div class="el-form-item-msg"></div>
  17. </el-form-item>
  18. </el-card>
  19. <template v-if="showNext">
  20. <el-card shadow="never" header="商家信息">
  21. <el-form-item label="收款方式" prop="settle_type">
  22. <el-radio-group v-model="formData.settle_type">
  23. <el-radio border :label="1">总店结算</el-radio>
  24. <el-radio border :label="2">分店结算</el-radio>
  25. <el-radio border :label="3">区域结算</el-radio>
  26. </el-radio-group>
  27. <div class="el-form-item-msg">
  28. <span v-if="formData.settle_type==1">现有支付账户统一接收该团购产生的所有账款 </span>
  29. <span v-if="formData.settle_type==2">若分店在消费者核销时未开通收款账户或未授权管理门店,则分店款项对应结算给公司账户或被授权的公司账户 </span>
  30. <span v-if="formData.settle_type==3">区域账户统一接收关联门店产生的所有账款,如分店未关联区域收款账户,该分店的款项自动结算给总店账户 </span>
  31. </div>
  32. </el-form-item>
  33. </el-card>
  34. <el-card shadow="never" header="商品信息">
  35. <el-form-item label="商品名称" prop="product_name">
  36. <el-input v-model="formData.product_name" maxlength="40" show-word-limit clearable placeholder="请输入"></el-input>
  37. <div class="el-form-item-msg"></div>
  38. </el-form-item>
  39. <el-row :gutter="15">
  40. <el-col :span="12">
  41. <el-form-item label="团购/次卡/代金券等划线价" prop="line_price">
  42. <el-input v-model="formData.line_price" type="number" clearable placeholder="请输入">
  43. <template #append>元</template>
  44. </el-input>
  45. <div class="el-form-item-msg"></div>
  46. </el-form-item>
  47. </el-col>
  48. <el-col :span="12">
  49. <el-form-item label="顾客实际需支付" prop="price">
  50. <el-input v-model="formData.price" type="number" clearable placeholder="请输入">
  51. <template #append>元</template>
  52. </el-input>
  53. <div class="el-form-item-msg"></div>
  54. </el-form-item>
  55. </el-col>
  56. </el-row>
  57. <fieldset>
  58. <legend><el-tag>商品搭配</el-tag></legend>
  59. <el-button type="primary" size="small" @click="addSpecs" v-if="specs.length<5">添加分组</el-button>
  60. <div class="specs" v-for="(item,indx) in specs" :key="indx">
  61. <div class="specs-header">
  62. <div class="specs-left">
  63. <el-input v-model="item.name" placeholder="请输入商品组名称" maxlength="10" show-word-limit clearable style="width: 50%;"></el-input>
  64. </div>
  65. <div class="specs-right">
  66. <el-select v-model="item.num" placeholder="请选择">
  67. <el-option :value="0" label="全部可选"></el-option>
  68. <el-option :value="len" :label="item.list.length+'选'+len" v-for="len in item.list.length" v-if="item.list.length > 1"></el-option>
  69. </el-select>
  70. </div>
  71. </div>
  72. <div class="specs-tips">商品组名称中不可出现“任选N”“X选N”字样,当商品组的可选范围是“几选1”或“全部可选”时,不可配置重复选</div>
  73. <div class="specs-body">
  74. <div class="body-item" v-for="(its,ind) in item.list" :key="ind">
  75. <div class="item-left">
  76. <el-row :gutter="10">
  77. <el-col :span="12" class="mb10">
  78. <el-input placeholder="请输入单品名称 " v-model="its.name">
  79. <template #prepend>名称</template>
  80. </el-input>
  81. </el-col>
  82. <el-col :span="12" class="mb10">
  83. <el-input placeholder="单价" v-model="its.price" type="number">
  84. <template #prepend>单价</template>
  85. <template #append>元</template>
  86. </el-input>
  87. </el-col>
  88. <el-col :span="12" class="mb10">
  89. <el-input placeholder="请输入重量 " v-model="its.weight" type="number">
  90. <template #prepend>重量</template>
  91. <template #append>
  92. <el-select v-model="its.weight_unit">
  93. <el-option value="kg" label="kg(千克)"></el-option>
  94. <el-option value="g" label="g(克)"></el-option>
  95. <el-option value="L" label="L(升)"></el-option>
  96. <el-option value="ml" label="ml(毫升)"></el-option>
  97. <el-option value="m" label="m(米)"></el-option>
  98. <el-option value="m²" label="m²(平方米)"></el-option>
  99. <el-option value="m³" label="m³(立方米)"></el-option>
  100. </el-select>
  101. </template>
  102. </el-input>
  103. </el-col>
  104. <el-col :span="12" class="mb10">
  105. <el-input placeholder="数量" v-model="its.number" type="number">
  106. <template #prepend>数量</template>
  107. <template #append>份</template>
  108. </el-input>
  109. </el-col>
  110. </el-row>
  111. </div>
  112. <div class="item-dels">
  113. <el-button type="danger" @click="removeItem(indx,ind)" circle icon="el-icon-delete" size="small"></el-button>
  114. </div>
  115. </div>
  116. </div>
  117. <div class="specs-footer">
  118. <el-button type="primary" @click="addItem(indx)">增加单品</el-button>
  119. <el-button type="danger" @click="removeSpec(indx)">删除组</el-button>
  120. </div>
  121. </div>
  122. </fieldset>
  123. <el-form-item label="多规格" prop="mult_sku">
  124. <el-radio-group v-model="formData.mult_sku">
  125. <el-radio border :label="1">关闭</el-radio>
  126. <el-radio border :label="2">开启</el-radio>
  127. </el-radio-group>
  128. <div class="el-form-item-msg"></div>
  129. </el-form-item>
  130. <fieldset v-if="formData.mult_sku == 2">
  131. <legend><el-tag>规格明细</el-tag></legend>
  132. <el-button type="primary" size="small" @click="addSkuSpecs" v-if="skuSpecs.length<5">新增规格</el-button>
  133. <div class="sku-table">
  134. <el-table :data="skuSpecs" border>
  135. <el-table-column prop="image" label="规格图片" width="180">
  136. <template #default="scope">
  137. <sc-upload v-model="scope.row.image" title="规格图片" :cropper="true" :compress="1" :aspectRatio="1/1"></sc-upload>
  138. </template>
  139. </el-table-column>
  140. <el-table-column prop="sku_id" label="商品ID(必填)" width="220">
  141. <template #default="scope">
  142. <el-input v-model="scope.row.sku_id" placeholder="商品ID"></el-input>
  143. </template>
  144. </el-table-column>
  145. <el-table-column prop="name" label="名称(必填)" width="220">
  146. <template #default="scope">
  147. <el-input v-model="scope.row.name" maxlength="40" show-word-limit placeholder="SKU名称"></el-input>
  148. </template>
  149. </el-table-column>
  150. <el-table-column prop="line_price" label="划线价(必填)" width="220">
  151. <template #default="scope">
  152. <el-input v-model="scope.row.line_price" type="number" placeholder="划线价">
  153. <template #append>元</template>
  154. </el-input>
  155. </template>
  156. </el-table-column>
  157. <el-table-column prop="price" label="支付价(必填)" width="220">
  158. <template #default="scope">
  159. <el-input v-model="scope.row.price" type="number" placeholder="支付价">
  160. <template #append>元</template>
  161. </el-input>
  162. </template>
  163. </el-table-column>
  164. <el-table-column label="操作" align="left" fixed="right">
  165. <template #default="scope">
  166. <el-button type="danger" size="small" @click="removeItemSku(scope.$index)" icon="el-icon-delete">删除</el-button>
  167. <el-button size="small" @click="itemSkuView(scope.$index,scope.row)">规格详情</el-button>
  168. </template>
  169. </el-table-column>
  170. </el-table>
  171. </div>
  172. </fieldset>
  173. <el-form-item label="商品头图" prop="image_list">
  174. <sc-upload-multiple v-model="formData.image_list" :multiple="false" draggable :limit="10" tip="图片尺寸不超过5M,图片越小呈现的速度越快,建议分辨率不低于750*562px"></sc-upload-multiple>
  175. <div class="el-form-item-msg"></div>
  176. </el-form-item>
  177. <el-form-item label="辅助图" prop="detail_image_list">
  178. <sc-upload-multiple v-model="formData.detail_image_list" :multiple="false" draggable :limit="4" tip="辅助图上传1-4张,每张图片不得超过5M,建议分辨率不低于750*562px"></sc-upload-multiple>
  179. <div class="el-form-item-msg"></div>
  180. </el-form-item>
  181. <el-form-item label="环境图" prop="environment_image_list">
  182. <sc-upload-multiple v-model="formData.environment_image_list" :multiple="false" draggable :limit="10" tip="良好的环境也是用户的优先选择,最多可上传10张。每张图片不得超过5M,建议分辨率不低于750*562px"></sc-upload-multiple>
  183. <div class="el-form-item-msg"></div>
  184. </el-form-item>
  185. </el-card>
  186. <el-card shadow="never" header="售卖信息">
  187. <el-form-item label="投放渠道" prop="show_channel">
  188. <el-radio-group v-model="formData.show_channel">
  189. <el-radio :label="1">不限制</el-radio>
  190. <el-popover placement="top-start" trigger="hover" content="用户仅可在直播间开播时支付购买,售价及库存均仅在直播间渠道生效。用户无法通过收藏或分享的商品链接支付购买。如希望以此售价通过多渠道分享和售卖,投放渠道需选择“不限制”。" :width="280">
  191. <template #reference>
  192. <el-radio :label="2">
  193. <template #default>
  194. <div class="radio-flex">仅直播间展示 <el-icon><el-icon-question-filled /></el-icon></div>
  195. </template>
  196. </el-radio>
  197. </template>
  198. </el-popover>
  199. <el-popover placement="top-start" trigger="hover" content="用户仅可通过线下二维码等物料购买,商品不会在线上任何渠道展示和售卖。" :width="280">
  200. <template #reference>
  201. <el-radio :label="5">
  202. <template #default>
  203. <div class="radio-flex">仅线下 <el-icon><el-icon-question-filled /></el-icon></div>
  204. </template>
  205. </el-radio>
  206. </template>
  207. </el-popover>
  208. <el-popover placement="top-start" trigger="hover" content="新用户只可在新人频道购买,售价及库存仅在新人频道生效,用户无法通过收藏或分享的商品链接支付购买。" :width="280">
  209. <template #reference>
  210. <el-radio :label="7">
  211. <template #default>
  212. <div class="radio-flex">仅新人频道 <el-icon><el-icon-question-filled /></el-icon></div>
  213. </template>
  214. </el-radio>
  215. </template>
  216. </el-popover>
  217. <el-popover placement="top-start" trigger="hover" content="用户可通过线上所有渠道购买(除新人频道),但不可通过线下二维码物料购买。" :width="280">
  218. <template #reference>
  219. <el-radio :label="8">
  220. <template #default>
  221. <div class="radio-flex">仅线上 <el-icon><el-icon-question-filled /></el-icon></div>
  222. </template>
  223. </el-radio>
  224. </template>
  225. </el-popover>
  226. <el-popover placement="top-start" trigger="hover" content="用户仅可在免费试频道购买,免费价格及库存仅针对参与免费试活动条件的用户生效。" :width="280">
  227. <template #reference>
  228. <el-radio :label="18">
  229. <template #default>
  230. <div class="radio-flex">仅免费试 <el-icon><el-icon-question-filled /></el-icon></div>
  231. </template>
  232. </el-radio>
  233. </template>
  234. </el-popover>
  235. <el-popover placement="top-start" trigger="hover" content="用户仅可在「团购」页面看到和购买商品。" :width="280">
  236. <template #reference>
  237. <el-radio :label="22">
  238. <template #default>
  239. <div class="radio-flex">仅团购商城 <el-icon><el-icon-question-filled /></el-icon></div>
  240. </template>
  241. </el-radio>
  242. </template>
  243. </el-popover>
  244. <el-popover placement="top-start" trigger="hover" content="商品售卖日期内,用户仅在直播间和获客卡渠道可支付购买,售价及库存均仅在直播间和获客卡渠道生效。" :width="280">
  245. <template #reference>
  246. <el-radio :label="23">
  247. <template #default>
  248. <div class="radio-flex">直播间+获客卡 <el-icon><el-icon-question-filled /></el-icon></div>
  249. </template>
  250. </el-radio>
  251. </template>
  252. </el-popover>
  253. <el-popover placement="top-start" trigger="hover" content="该渠道商品不会在常规渠道售卖,需报名参加营销活动进行售卖。" :width="280">
  254. <template #reference>
  255. <el-radio :label="25">
  256. <template #default>
  257. <div class="radio-flex">仅活动报名 <el-icon><el-icon-question-filled /></el-icon></div>
  258. </template>
  259. </el-radio>
  260. </template>
  261. </el-popover>
  262. </el-radio-group>
  263. <div class="el-form-item-msg"></div>
  264. </el-form-item>
  265. <el-form-item label="库存数量" prop="limit_use_rule">
  266. <el-radio-group v-model="formData.limit_use_rule">
  267. <el-radio :label="2">不限制</el-radio>
  268. <el-radio :label="1">限库存</el-radio>
  269. </el-radio-group>
  270. </el-form-item>
  271. <el-form-item label="团购库存数量" prop="use_num_per_consume" v-if="formData.limit_use_rule==1">
  272. <el-input v-model="formData.use_num_per_consume" style="width: 30%;">
  273. <template #append>份</template>
  274. </el-input>
  275. </el-form-item>
  276. <el-form-item label="商品售卖日期" prop="sold_start_times">
  277. <div style="width: 30%;">
  278. <el-date-picker v-model="formData.sold_start_times" placeholder="请选择商品售卖日期" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" />
  279. </div>
  280. <div class="el-form-item-msg">顾客可以在这个时间内购买商品,超过这个日期,活动自动下线</div>
  281. </el-form-item>
  282. <div class="radio-flex">
  283. 自动延期<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"/>
  284. <span class="fs12">团购到期后自动延长30天(有效期同时延长),可随时关闭。</span>
  285. </div>
  286. </el-card>
  287. <el-card shadow="never" header="交易规则">
  288. <el-form-item label="顾客可消费日期" prop="use_date_type">
  289. <el-radio-group v-model="formData.use_date_type">
  290. <el-radio :label="1">指定天数</el-radio>
  291. <el-radio :label="2">指定日期</el-radio>
  292. </el-radio-group>
  293. <div class="el-form-item-msg" v-if="formData.use_date_type==1"></div>
  294. <div class="el-form-item-msg" v-if="formData.use_date_type==2">
  295. 可使用日期的结束时间必须晚于售卖日期的结束时间
  296. </div>
  297. <div v-if="formData.use_date_type==1">
  298. <el-input v-model="formData.day_duration">
  299. <template #append>天,购买当日默认可用</template>
  300. <template #prepend>自购买次日起</template>
  301. </el-input>
  302. </div>
  303. <div v-if="formData.use_date_type==2" style="width: 30%;">
  304. <el-date-picker v-model="formData.use_times" placeholder="请选择商品售卖日期" start-placeholder="开始时间" end-placeholder="结束时间" type="daterange" range-separator="至" />
  305. </div>
  306. </el-form-item>
  307. <el-form-item label="顾客不可消费日期" prop="can_no_use_date">
  308. <el-radio-group v-model="formData.can_no_use_date">
  309. <el-radio :label="1">所有日期均可使用</el-radio>
  310. <!-- <el-radio :label="2">部分日期不可用</el-radio> -->
  311. </el-radio-group>
  312. <div class="el-form-item-msg"></div>
  313. </el-form-item>
  314. <el-form-item label="券码类型" prop="code_source_type">
  315. <el-radio-group v-model="formData.code_source_type" disabled>
  316. <el-radio :label="1">抖音码</el-radio>
  317. <el-radio :label="2">三方码</el-radio>
  318. </el-radio-group>
  319. <div class="el-form-item-msg"></div>
  320. </el-form-item>
  321. </el-card>
  322. <el-card shadow="never" header="消费规则">
  323. <el-form-item label="限购规则" prop="limit_rule_type">
  324. <el-radio-group v-model="formData.limit_rule_type">
  325. <el-radio :label="1">不限制购买</el-radio>
  326. <el-radio :label="2">限制购买</el-radio>
  327. </el-radio-group>
  328. <div class="el-form-item-msg"></div>
  329. <div v-if="formData.limit_rule_type==2">
  330. <el-input v-model="formData.limit_rule">
  331. <template #append>份</template>
  332. <template #prepend>限制每人最多购买</template>
  333. </el-input>
  334. </div>
  335. </el-form-item>
  336. <el-form-item label="预约规则" prop="booking_type">
  337. <el-radio-group v-model="formData.booking_type">
  338. <el-radio :label="1">无需预约</el-radio>
  339. <el-radio :label="2">到店前需要预约</el-radio>
  340. </el-radio-group>
  341. <div class="el-form-item-msg"></div>
  342. <div v-if="formData.booking_type==2">
  343. <el-input v-model="formData.booking_date">
  344. <template #prepend>需提前电话预约</template>
  345. <template #append>
  346. <el-select v-model="formData.booking_unit" style="width: 80px;">
  347. <el-option :value="1" label="天"></el-option>
  348. <el-option :value="2" label="小时"></el-option>
  349. </el-select>
  350. </template>
  351. </el-input>
  352. </div>
  353. </el-form-item>
  354. <el-form-item label="使用张数限制" prop="rec_person_type">
  355. <el-radio-group v-model="formData.rec_person_type">
  356. <el-radio :label="1">不限制张数</el-radio>
  357. <el-radio :label="2">限制张数</el-radio>
  358. </el-radio-group>
  359. <div class="el-form-item-msg"></div>
  360. <div v-if="formData.rec_person_type==2">
  361. <el-input v-model="formData.rec_person_num_max">
  362. <template #prepend>单次消费最多使用张数</template>
  363. <template #append>张</template>
  364. </el-input>
  365. </div>
  366. </el-form-item>
  367. </el-card>
  368. </template>
  369. </el-form>
  370. </el-col>
  371. <el-col :span="6">
  372. <el-card shadow="never" header="详情预览">
  373. <div class="sub-tips">该功能只做预览,实际效果以真机为准</div>
  374. <div class="preview-mobile">
  375. <div class="mobile-bannber">
  376. <el-carousel :interval="5000" arrow="always">
  377. <el-carousel-item v-for="item in formData.image_list" :key="item">
  378. <el-image :src="item.url"></el-image>
  379. </el-carousel-item>
  380. </el-carousel>
  381. </div>
  382. <div class="mobile-info">
  383. <div class="info-price">
  384. <span class="price">{{ formData.price?$TOOL.moneyFormat(formData.price):'¥0.00' }}</span>
  385. <span class="line">{{ formData.line_price?$TOOL.moneyFormat(formData.line_price):'¥0.00' }}</span>
  386. <span class="dis">{{ $TOOL.disFormat(formData.price,formData.line_price) }}折</span>
  387. </div>
  388. <div class="info-title">{{ formData.product_name?formData.product_name:'演示商品标题' }}</div>
  389. <div class="sku-list" v-if="skuSpecs.length > 0">
  390. <div class="sku-title">规格<br>选择</div>
  391. <div class="sku-list-body">
  392. <div class="sku-item" v-for="(item,indx) in skuSpecs" :key="indx">{{item.name}}</div>
  393. </div>
  394. </div>
  395. <div class="item-tag">
  396. <div class="tag-li"><el-icon color="#f00" size="14"><el-icon-circle-check /></el-icon>过期退</div>
  397. <div class="tag-li"><el-icon color="#f00" size="14"><el-icon-circle-check /></el-icon>随时退</div>
  398. </div>
  399. </div>
  400. <div class="mobile-group">
  401. <div class="group-title">团购套餐</div>
  402. <div class="group-body" v-if="specs.length > 0" v-for="(item,indx) in specs" :key="indx">
  403. <div class="body-title">
  404. {{item.name}}
  405. <span v-if="item.num == 0">全部可选</span>
  406. <span v-else>{{item.list.length}}选{{item.num}}</span>
  407. </div>
  408. <div class="body-item">
  409. <div class="body-item-li" v-for="(its,idx) in item.list" :key="idx">
  410. {{its.name}}
  411. <div class="item-right">
  412. <span>({{its.number}}份)</span>
  413. <span>{{$TOOL.moneyFormat(its.price)}}</span>
  414. </div>
  415. </div>
  416. </div>
  417. </div>
  418. </div>
  419. <div class="mobile-group">
  420. <div class="group-title">购买须知</div>
  421. <div class="group-mix">
  422. <div class="mix-title">
  423. <el-icon size="14" color="#000"><el-icon-suitcase /></el-icon>有效期
  424. </div>
  425. <div class="mix-item" v-if="formData.use_date_type==1">
  426. 购买后 <span>{{ formData.day_duration }}</span> 天有效
  427. </div>
  428. <div class="mix-item" v-if="formData.use_date_type==2">
  429. <span v-if="formData.use_times">
  430. {{ $TOOL.dateFormat(formData.use_times[0],'yyyy-MM-dd') }}至{{ $TOOL.dateFormat(formData.use_times[1],'yyyy-MM-dd') }}
  431. </span>
  432. </div>
  433. </div>
  434. <div class="group-mix">
  435. <div class="mix-title">
  436. <el-icon size="14" color="#000"><el-icon-clock /></el-icon>可用时间
  437. </div>
  438. <div class="mix-item" v-if="formData.can_no_use_date==1">
  439. 商家营业时间可用
  440. </div>
  441. </div>
  442. <div class="group-mix">
  443. <div class="mix-title">
  444. <el-icon size="14" color="#000"><el-icon-alarm-clock /></el-icon>预约规则
  445. </div>
  446. <div class="mix-item" v-if="formData.booking_type==1">
  447. 无需预约,高峰期可能需要排队
  448. </div>
  449. <div class="mix-item" v-if="formData.booking_type==2">
  450. 需要提前<span>{{ formData.booking_date }}</span>{{ formData.booking_unit==1?'天':'小时' }}预约
  451. </div>
  452. </div>
  453. </div>
  454. </div>
  455. </el-card>
  456. </el-col>
  457. </el-row>
  458. </el-main>
  459. <el-footer style="text-align: center;">
  460. <el-button @click="reback" size="large">取 消</el-button>
  461. <el-button size="large" type="primary" :loading="isSaveing" @click="submit()">提交审核</el-button>
  462. </el-footer>
  463. </el-container>
  464. <skuView ref="skuView" @success="skuResp"></skuView>
  465. </template>
  466. <script>
  467. import dayjs from 'dayjs';
  468. import skuView from './components/sku'
  469. export default {
  470. components:{
  471. skuView
  472. },
  473. data(){
  474. return {
  475. isSaveing:false,
  476. showNext:false,
  477. formData:{
  478. settle_type:1,
  479. show_channel:1,
  480. limit_use_rule:1,
  481. auto_renew:true,
  482. use_date_type:1,
  483. day_duration:30,
  484. can_no_use_date:1,
  485. code_source_type:1,
  486. limit_rule_type:1,
  487. limit_rule:1,
  488. booking_date:1,
  489. booking_type:1,
  490. booking_unit:1,
  491. rec_person_type:1,
  492. rec_person_num_max:1,
  493. image_list:[],
  494. mult_sku:1
  495. },
  496. specs:[{"name":"","num":0,"list":[ {"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1} ]}],
  497. skuSpecs:[],
  498. channelLoad:false,
  499. rules:{
  500. line_price: [
  501. {required: true, message: '请输入'}
  502. ],
  503. price: [
  504. {required: true, message: '请输入'}
  505. ],
  506. image_list: [
  507. {required: true, message: '请上传'}
  508. ],
  509. rec_person_type: [
  510. {required: true, message: '请选择'}
  511. ],
  512. code_source_type: [
  513. {required: true, message: '请选择'}
  514. ],
  515. can_no_use_date: [
  516. {required: true, message: '请选择'}
  517. ],
  518. use_date_type: [
  519. {required: true, message: '请选择'}
  520. ],
  521. product_name: [
  522. {required: true, message: '请输入'}
  523. ],
  524. use_num_per_consume: [
  525. {required: true, message: '请输入'}
  526. ],
  527. limit_use_rule: [
  528. {required: true, message: '请选择'}
  529. ],
  530. sold_start_times: [
  531. {required: true, message: '请选择'}
  532. ],
  533. show_channel: [
  534. {required: true, message: '请选择'}
  535. ],
  536. settle_type: [
  537. {required: true, message: '请选择'}
  538. ],
  539. category: [
  540. {required: true, message: '请选择'}
  541. ],
  542. product_type: [
  543. {required: true, message: '请选择'}
  544. ],
  545. },
  546. deptsProps:{
  547. value: "category_id",
  548. label: "name"
  549. },
  550. typeData:[],
  551. categoryData:[]
  552. }
  553. },
  554. created(){
  555. this.getData()
  556. this.formData.sold_start_times = this.formattedCurrentDate();
  557. },
  558. methods: {
  559. skuResp(data){
  560. this.skuSpecs[data.index] = data.data;
  561. },
  562. itemSkuView(index,data){
  563. this.$nextTick(() => {
  564. this.$refs.skuView.open("edit").setData(index,data)
  565. })
  566. },
  567. addSkuSpecs(){
  568. this.skuSpecs.push({"image":"","sku_id":this.generate(),"name":"","line_price":1,"price":1,"is_default":false,"specs":[]});
  569. },
  570. removeItemSku(index){
  571. this.skuSpecs.splice(index,1)
  572. },
  573. addSpecs(){
  574. if (this.specs.length >= 5) {
  575. return this.$message.error("最多只能添加三组规格")
  576. }
  577. this.specs.push({"name":"","num":0,"list":[ {"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1} ]});
  578. },
  579. addItem(index){
  580. if (this.specs[index].list.length >= 20) {
  581. return this.$message.error("最多只能添加20个")
  582. }
  583. this.specs[index].list.push({"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1})
  584. },
  585. removeSpec(index){
  586. this.specs.splice(index,1)
  587. },
  588. removeItem(index,sub){
  589. this.specs[index].list.splice(sub,1)
  590. },
  591. generate() {
  592. let timestamp = Date.now();
  593. if (timestamp === this.lastTimestamp) {
  594. this.sequence++;
  595. } else {
  596. this.sequence = 0;
  597. this.lastTimestamp = timestamp;
  598. }
  599. const randomPart = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
  600. const timestampPart = timestamp.toString().slice(-6); // 取时间戳后6位
  601. const seqPart = this.sequence.toString().padStart(2, '0'); // 序列号占2位(0-99)
  602. let base = timestampPart + seqPart + randomPart; // 6+2+4=12位
  603. const remainingLength = 18 - base.length;
  604. const extraRandom = Math.floor(Math.random() * Math.pow(10, remainingLength)).toString().padStart(remainingLength, '0');
  605. return base + extraRandom; // 最终18位字符串
  606. },
  607. formattedCurrentDate() {
  608. const now = dayjs();
  609. const currentDate = now.format('YYYY-MM-DD HH:mm:ss');
  610. const nextYearDate = now.add(1, 'year').format('YYYY-MM-DD HH:mm:ss');
  611. return [currentDate,nextYearDate];
  612. },
  613. async getTemplate(){
  614. var { formData, $message } = this;
  615. if (formData.product_type && formData.category) {
  616. // var resp = await this.$API.merGoods.template.post({"product_type":formData.product_type,"category":formData.category});
  617. this.showNext = true;
  618. return ;
  619. }
  620. },
  621. async getData(){
  622. this.channelLoad = true;
  623. var resp = await this.$API.category.list.get();
  624. if (resp.code == 0) {
  625. return this.$message.error(resp.msg)
  626. }
  627. this.categoryData = resp.data;
  628. this.getCate()
  629. },
  630. async getCate(){
  631. var resp = await this.$API.merGoods.type.get();
  632. this.channelLoad = false;
  633. if (resp.code == 0) {
  634. return this.$message.error(resp.msg)
  635. }
  636. this.typeData = resp.data;
  637. },
  638. reback(){
  639. this.$confirm(`确定要退出添加商品吗?`, '提示', {
  640. type: 'warning'
  641. }).then(() => {
  642. this.$router.go(-1)
  643. }).catch(() => {
  644. })
  645. },
  646. async submit(){
  647. var { formData, $message } = this;
  648. var validate = await this.$refs.dialogForm.validate().catch(()=>{});
  649. if(!validate){ return false }
  650. formData.specs = this.specs;
  651. formData.skuSpecs = this.skuSpecs;
  652. if (formData.sold_start_times) {
  653. var sold_start_time = formData.sold_start_times;
  654. formData.sold_start_time = this.$TOOL.dateFormat(sold_start_time[0],"yyyy-MM-dd")
  655. formData.sold_end_time = this.$TOOL.dateFormat(sold_start_time[1],"yyyy-MM-dd")
  656. }
  657. if (formData.use_times) {
  658. var use_time = formData.use_times;
  659. formData.use_time_start = this.$TOOL.dateFormat(use_time[0],"yyyy-MM-dd")
  660. formData.use_time_end = this.$TOOL.dateFormat(use_time[1],"yyyy-MM-dd")
  661. }
  662. this.isSaveing = true;
  663. var resp = await this.$API.merGoods.save.post(formData);
  664. this.isSaveing = false;
  665. if (resp.code == 0) {
  666. return $message.error(resp.msg)
  667. }
  668. $message.success(resp.msg)
  669. this.$router.go(-1)
  670. }
  671. }
  672. }
  673. </script>
  674. <style scoped>
  675. .group-mix .mix-title{display: flex;align-items: center;line-height: 32px;font-weight: bold;font-size: 12px;gap: 5px;}
  676. .group-mix .mix-item{padding-left: 10px;position: relative;line-height: 32px;margin-left: 10px;}
  677. .group-mix .mix-item span{color: orange;padding: 0 5px;}
  678. .group-mix .mix-item::after{position: absolute;top: 0;width: 5px;height: 5px;background-color: #000;border-radius: 5px;content: "";left: 0;top: 38%;}
  679. .mobile-group{background-color: #fff;margin-top: 10px;padding: 10px;}
  680. .mobile-group .group-title{font-size: 14px;font-weight: bold;color: #333;line-height: 36px;}
  681. .mobile-group .body-title{display: flex;align-items: center;line-height: 32px;font-size: 14px;color: #333;font-weight: bold;gap: 8px;}
  682. .mobile-group .body-title span{font-size: 12px;font-weight: normal;color: #666;}
  683. .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;}
  684. .mobile-group .body-item-li .item-right{display: flex;align-items: center;gap: 10px;}
  685. .mobile-bannber{background-color: #f8f8f8;}
  686. .mobile-info{padding: 10px;background-color: #fff;}
  687. .mobile-info .info-title{font-size: 14px;font-weight: bold;line-height: 36px;}
  688. .mobile-info .info-price{display: flex;align-items: flex-end;gap: 8px;}
  689. .mobile-info .info-price .price{color: #f00;font-size: 22px;font-weight: bold;}
  690. .mobile-info .info-price .line{color: #666;font-size: 12px;text-decoration:line-through;}
  691. .mobile-info .info-price .dis{background-color: rgb(255, 234, 234);;color: rgb(255, 68, 68);;padding: 5px;border-radius: 2px;}
  692. .mobile-info .item-tag{display: flex;align-items: center;gap: 10px;font-size: 12px;}
  693. .mobile-info .item-tag .tag-li{display: flex;align-items: center;gap: 5px;}
  694. .mobile-info .sku-list{display: flex;align-items: center;margin: 10px 0;}
  695. .mobile-info .sku-list .sku-title{color: #999090;font-size: 12px;}
  696. .mobile-info .sku-list .sku-list-body{display: flex;align-items: center;margin-left: 8px;flex: 1;overflow: hidden;overflow-x: auto;gap: 8px;}
  697. .mobile-info .sku-list .sku-list-body .sku-item{background-color: #f6fafd;padding: 8px 16px;border-radius: 8px;text-wrap: nowrap;}
  698. .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;}
  699. .radio-flex{display: flex;align-items: center;gap: 5px;}
  700. .fs12{color: #999;font-size: 12px;}
  701. .specs{margin-top: 15px;background-color: #f8f8f8;}
  702. .specs-header{
  703. display: flex;
  704. background-color: #ddd;
  705. padding: 10px;
  706. }
  707. .specs-tips{
  708. padding: 0 10px 10px 10px;
  709. background-color: #ddd;
  710. }
  711. .specs-header .specs-left{
  712. display: flex;
  713. align-items: center;
  714. flex: 1;
  715. gap: 10px;
  716. }
  717. .specs-header .specs-right{
  718. display: flex;
  719. margin-left: auto;
  720. margin-right: 0;
  721. }
  722. .specs-body{display: flex;align-items: center;gap: 10px;padding: 10px;flex-direction: row;flex-wrap: wrap;}
  723. .specs-body .body-item{padding: 5px;display: flex;align-items: center;}
  724. .specs-body .body-item .item-dels{margin-left: 10px;}
  725. .item-img{margin-bottom: 5px;}
  726. .mb10{margin-bottom: 10px;}
  727. .specs-footer{background-color: #ddd;padding: 10px;}
  728. .sku-table{margin-top: 10px;}
  729. .el-upload__tip,
  730. .el-upload-list__item,
  731. .el-dialog__wrapper {
  732. z-index: 9999 !important;
  733. }
  734. </style>