index.vue 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  4. <el-form-item label="商品分类" prop="cateId">
  5. <treeselect v-model="queryParams.cateId" style="width:205.4px" :options="categoryOptions" :normalizer="normalizer" placeholder="请选择分类" />
  6. </el-form-item>
  7. <el-form-item label="商品名称" prop="productName">
  8. <el-input
  9. v-model="queryParams.productName"
  10. placeholder="请输入商品名称"
  11. clearable
  12. size="small"
  13. @keyup.enter.native="handleQuery"
  14. />
  15. </el-form-item>
  16. <el-form-item label="商品类型" prop="productType">
  17. <el-select v-model="queryParams.productType" placeholder="请选择商品类型" clearable size="small" >
  18. <el-option
  19. v-for="item in productTypeOptions"
  20. :key="item.dictValue"
  21. :label="item.dictLabel"
  22. :value="item.dictValue"
  23. />
  24. </el-select>
  25. </el-form-item>
  26. <!-- <el-form-item label="状态" prop="isShow">
  27. <el-select style="width: 240px" v-model="queryParams.isShow" placeholder="请选择状态" clearable size="small" >
  28. <el-option
  29. v-for="item in isShowOptions"
  30. :key="item.dictValue"
  31. :label="item.dictLabel"
  32. :value="item.dictValue"
  33. />
  34. </el-select>
  35. </el-form-item> -->
  36. <el-form-item>
  37. <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  38. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  39. </el-form-item>
  40. </el-form>
  41. <el-row :gutter="10" class="mb8">
  42. <el-col :span="1.5">
  43. <el-button
  44. type="primary"
  45. icon="el-icon-plus"
  46. size="mini"
  47. @click="handleAdd"
  48. v-hasPermi="['store:storeProduct:add']"
  49. >新增</el-button>
  50. </el-col>
  51. <el-col :span="1.5">
  52. <el-button
  53. type="success"
  54. icon="el-icon-edit"
  55. size="mini"
  56. :disabled="single"
  57. @click="handleUpdate"
  58. v-hasPermi="['store:storeProduct:edit']"
  59. >修改</el-button>
  60. </el-col>
  61. <el-col :span="1.5">
  62. <el-button
  63. type="danger"
  64. icon="el-icon-delete"
  65. size="mini"
  66. :disabled="multiple"
  67. @click="handleDelete"
  68. v-hasPermi="['store:storeProduct:remove']"
  69. >删除</el-button>
  70. </el-col>
  71. <el-col :span="1.5">
  72. <el-button
  73. type="warning"
  74. icon="el-icon-download"
  75. size="mini"
  76. @click="handleExport"
  77. v-hasPermi="['store:storePayment:export']"
  78. >导出</el-button>
  79. </el-col>
  80. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  81. </el-row>
  82. <el-tabs type="card" v-model="activeName" @tab-click="handleClick">
  83. <el-tab-pane label="出售中" name="1"></el-tab-pane>
  84. <el-tab-pane label="待上架" name="0"></el-tab-pane>
  85. </el-tabs>
  86. <el-table height="500" border v-loading="loading" :data="storeProductList" @selection-change="handleSelectionChange">
  87. <el-table-column type="selection" width="55" align="center" />
  88. <el-table-column label="ID" align="center" prop="productId" />
  89. <el-table-column label="商品图片" align="center" width="120">
  90. <template slot-scope="scope">
  91. <el-popover
  92. placement="right"
  93. title=""
  94. trigger="hover"
  95. >
  96. <img slot="reference" :src="scope.row.image" width="100">
  97. <img :src="scope.row.image" style="max-width: 150px;">
  98. </el-popover>
  99. </template>
  100. </el-table-column>
  101. <el-table-column label="商品名称" show-overflow-tooltip align="center" prop="productName" />
  102. <el-table-column label="分类" align="center" prop="cateName" />
  103. <el-table-column label="售价" align="center" prop="price" >
  104. <template slot-scope="scope" >
  105. <span v-if="scope.row.price!=null">{{scope.row.price.toFixed(2)}}</span>
  106. </template>
  107. </el-table-column>
  108. <el-table-column label="原价" align="center" prop="otPrice" >
  109. <template slot-scope="scope" >
  110. <span v-if="scope.row.otPrice!=null">{{scope.row.otPrice.toFixed(2)}}</span>
  111. </template>
  112. </el-table-column>
  113. <el-table-column label="销量" align="center" prop="sales" />
  114. <el-table-column label="库存" align="center" prop="stock" />
  115. <el-table-column label="类型" align="center" prop="productType" >
  116. <template slot-scope="scope">
  117. <el-tag prop="productType" v-for="(item, index) in productTypeOptions" v-if="scope.row.productType==item.dictValue">{{item.dictLabel}}</el-tag>
  118. </template>
  119. </el-table-column>
  120. <el-table-column label="状态" align="center" prop="isShow" >
  121. <template slot-scope="scope">
  122. <el-tag prop="status" v-for="(item, index) in isShowOptions" v-if="scope.row.isShow==item.dictValue">{{item.dictLabel}}</el-tag>
  123. </template>
  124. </el-table-column>
  125. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  126. <template slot-scope="scope">
  127. <el-button
  128. size="mini"
  129. type="text"
  130. icon="el-icon-edit"
  131. @click="handleUpdate(scope.row)"
  132. v-hasPermi="['store:storeProduct:edit']"
  133. >修改</el-button>
  134. <el-button
  135. size="mini"
  136. type="text"
  137. icon="el-icon-delete"
  138. @click="handleDelete(scope.row)"
  139. v-hasPermi="['store:storeProduct:remove']"
  140. >删除</el-button>
  141. </template>
  142. </el-table-column>
  143. </el-table>
  144. <pagination
  145. v-show="total>0"
  146. :total="total"
  147. :page.sync="queryParams.pageNum"
  148. :limit.sync="queryParams.pageSize"
  149. @pagination="getList"
  150. />
  151. <!-- 添加或修改商品对话框 -->
  152. <el-dialog :title="title" v-if="open" :visible.sync="open" width="1000px" append-to-body>
  153. <el-form ref="form" :model="form" :rules="rules" label-width="100px">
  154. <el-row >
  155. <el-col :span="12">
  156. <el-form-item label="商品名称" prop="productName">
  157. <el-input v-model="form.productName" placeholder="请输入商品名称" />
  158. </el-form-item>
  159. </el-col>
  160. <el-col :span="12">
  161. <el-form-item label="商品分类" prop="cateId">
  162. <treeselect v-model="form.cateId" :options="categoryOptions" :normalizer="normalizer" placeholder="请选择上级分类" />
  163. </el-form-item>
  164. </el-col>
  165. </el-row>
  166. <el-row>
  167. <el-col :span="12">
  168. <el-form-item label="关键字" prop="keyword">
  169. <el-input v-model="form.keyword" placeholder="请输入关键字" />
  170. </el-form-item>
  171. </el-col>
  172. <el-col :span="12">
  173. <el-form-item label="单位名" prop="unitName">
  174. <el-input v-model="form.unitName" placeholder="请输入单位名" />
  175. </el-form-item>
  176. </el-col>
  177. </el-row>
  178. <el-row>
  179. <el-col :span="24">
  180. <el-form-item label="商品简介" prop="productInfo">
  181. <el-input v-model="form.productInfo" type="textarea" :rows="2" placeholder="请输入商品简介" />
  182. </el-form-item>
  183. </el-col>
  184. </el-row>
  185. <el-form-item label="商品图片" prop="image">
  186. <Material v-model="imageArr" type="image" :num="1" :width="150" :height="150" />
  187. </el-form-item>
  188. <el-form-item label="轮播图" prop="sliderImage">
  189. <Material v-model="photoArr" type="image" :num="10" :width="150" :height="150" />
  190. </el-form-item>
  191. <el-row>
  192. <el-col :span="24">
  193. <el-form-item label="商品规格:" props="specType">
  194. <el-radio-group v-model="form.specType" >
  195. <el-radio :label="0" class="radio">单规格</el-radio>
  196. <el-radio :label="1">多规格</el-radio>
  197. </el-radio-group>
  198. </el-form-item>
  199. </el-col>
  200. <!-- 多规格添加-->
  201. <el-col :span="24" v-if="form.specType === 1" class="noForm">
  202. <el-col :span="24">
  203. <el-form-item label="选择规格:" prop="">
  204. <div class="acea-row row-middle">
  205. <el-select v-model="form.selectRule" style="width: 23%;">
  206. <el-option v-for="(item, index) in ruleList" :value="item.ruleName" :key="index">{{ item.ruleName }}</el-option>
  207. </el-select>
  208. <el-button style="margin-left:10px;" type="primary" class="mr20" @click="confirm">确认</el-button>
  209. </div>
  210. </el-form-item>
  211. </el-col>
  212. <el-col :span="24">
  213. <el-form-item v-if="attrs!=null&&attrs.length!==0">
  214. <div v-for="(item, index) in attrs" :key="index">
  215. <div class="acea-row row-middle"><span class="mr5">{{item.value}}</span>
  216. <i class="el-icon-circle-close" @click="handleRemoveRole(index)"></i>
  217. </div>
  218. <div class="rulesBox">
  219. <el-tag type="dot" closable color="primary" v-for="(j, indexn) in item.detail" :key="indexn" :name="j" class="mr20" @close="handleRemove2(item.detail,indexn)">{{j}}</el-tag>
  220. <el-input placeholder="请输入属性名称" v-model="item.detail.attrsVal"
  221. style="width: 200px">
  222. <el-button slot="append" type="primary" @click="createAttr(item.detail.attrsVal,index)">添加</el-button>
  223. </el-input>
  224. </div>
  225. </div>
  226. </el-form-item>
  227. </el-col>
  228. <el-col :span="24" v-if="createBnt">
  229. <el-form-item>
  230. <el-button type="primary" size="small" icon="md-add" @click="addBtn" class="mr15">添加新规格</el-button>
  231. <el-button type="success" size="small" @click="generate">立即生成</el-button>
  232. </el-form-item>
  233. </el-col>
  234. <el-col :span="24" v-if="showIput">
  235. <el-col :xl="6" :lg="9" :md="10" :sm="24" :xs="24" >
  236. <el-form-item label="规格:">
  237. <el-input placeholder="请输入规格" v-model="formDynamic.attrsName" />
  238. </el-form-item>
  239. </el-col>
  240. <el-col :xl="6" :lg="9" :md="10" :sm="24" :xs="24">
  241. <el-form-item label="规格值:">
  242. <el-input v-model="formDynamic.attrsVal" placeholder="请输入规格值" />
  243. </el-form-item>
  244. </el-col>
  245. <el-col :xl="6" :lg="5" :md="10" :sm="24" :xs="24" >
  246. <el-button type="primary" @click="createAttrName">确定</el-button>
  247. <el-button type="danger" @click="closeAttrName" >取消</el-button>
  248. </el-col>
  249. </el-col>
  250. <!-- 多规格设置-->
  251. <el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24" v-if="manyFormValidate!=null&&manyFormValidate.length">
  252. <!-- 多规格表格-->
  253. <el-col :span="24">
  254. <el-form-item label="商品属性:" class="labeltop">
  255. <el-table :data="manyFormValidate" size="small" style="width: 90%;">
  256. <el-table-column type="myindex" v-for="(item,index) in form.header" :key="index" :width="item.minWidth" :label="item.title" :property="item.slot" align="center">
  257. <template slot-scope="scope">
  258. <div v-if="scope.column.property == 'image'" align="center">
  259. <single-img v-model="scope.row[scope.column.property]" type="image" :num="1" :width="60" :height="60" />
  260. </div>
  261. <div v-else-if="scope.column.property.indexOf('value') != -1" align="center">
  262. {{ scope.row[scope.column.property] }}
  263. </div>
  264. <div v-else-if="scope.column.property == 'action'" align="center" >
  265. <a @click="delAttrTable(scope.$index)" align="center">删除</a>
  266. </div>
  267. <div v-else align="center">
  268. <el-input v-model="scope.row[scope.column.property]" align="center" />
  269. </div>
  270. </template>
  271. </el-table-column>
  272. </el-table>
  273. </el-form-item>
  274. </el-col>
  275. </el-col>
  276. </el-col>
  277. <!-- 单规格表格-->
  278. <el-col :xl="23" :lg="24" :md="24" :sm="24" :xs="24" v-if="form.specType === 0">
  279. <el-form-item >
  280. <el-table :data="oneFormValidate" size="small" style="width: 90%;">
  281. <el-table-column prop="image" label="图片" align="center">
  282. <template slot-scope="scope">
  283. <single-img v-model="scope.row.image" type="image" :num="1" :width="60" :height="60" />
  284. </template>
  285. </el-table-column>
  286. <el-table-column prop="price" label="售价" align="center">
  287. <template slot-scope="scope">
  288. <el-input type="text" v-model="scope.row.price"/>
  289. </template>
  290. </el-table-column>
  291. <el-table-column prop="price" label="代理价" align="center">
  292. <template slot-scope="scope">
  293. <el-input type="text" v-model="scope.row.agentPrice"/>
  294. </template>
  295. </el-table-column>
  296. <el-table-column prop="cost" label="成本价" align="center">
  297. <template slot-scope="scope">
  298. <el-input type="text" v-model="scope.row.cost"/>
  299. </template>
  300. </el-table-column>
  301. <el-table-column prop="otPrice" label="原价" align="center">
  302. <template slot-scope="scope">
  303. <el-input type="text" v-model="scope.row.otPrice"/>
  304. </template>
  305. </el-table-column>
  306. <el-table-column prop="stock" label="库存" align="center">
  307. <template slot-scope="scope">
  308. <el-input type="text" v-model="scope.row.stock" maxlength="7"/>
  309. </template>
  310. </el-table-column>
  311. <el-table-column prop="barCode" label="商品编号" width="130px" align="center">
  312. <template slot-scope="scope">
  313. <el-input type="text" v-model="scope.row.barCode"/>
  314. </template>
  315. </el-table-column>
  316. <el-table-column prop="barCode" label="组合编号" width="130px" align="center">
  317. <template slot-scope="scope">
  318. <el-input type="text" v-model="scope.row.groupBarCode"/>
  319. </template>
  320. </el-table-column>
  321. <el-table-column prop="weight" label="重量(KG)" align="center">
  322. <template slot-scope="scope">
  323. <el-input type="text" v-model="scope.row.weight"/>
  324. </template>
  325. </el-table-column>
  326. <el-table-column prop="volume" label="体积(m³)" align="center">
  327. <template slot-scope="scope">
  328. <el-input type="text" v-model="scope.row.volume"/>
  329. </template>
  330. </el-table-column>
  331. <el-table-column prop="volume" label="所需积分" align="center">
  332. <template slot-scope="scope">
  333. <el-input type="text" v-model="scope.row.integral"/>
  334. </template>
  335. </el-table-column>
  336. <el-table-column prop="volume" label="一级返佣" align="center">
  337. <template slot-scope="scope">
  338. <el-input type="text" v-model="scope.row.brokerage"/>
  339. </template>
  340. </el-table-column>
  341. <el-table-column prop="volume" label="二级返佣" align="center">
  342. <template slot-scope="scope">
  343. <el-input type="text" v-model="scope.row.brokerageTwo"/>
  344. </template>
  345. </el-table-column>
  346. <el-table-column prop="volume" label="三级返佣" align="center">
  347. <template slot-scope="scope">
  348. <el-input type="text" v-model="scope.row.brokerageThree"/>
  349. </template>
  350. </el-table-column>
  351. </el-table>
  352. </el-form-item>
  353. </el-col>
  354. <el-col :span="24">
  355. <el-form-item label="运费模板:" prop="tempId">
  356. <div class="acea-row">
  357. <el-select v-model="form.tempId" class="mr20">
  358. <el-option v-for="(item,index) in templateList" :value="item.id" :key="index" :label="item.name">
  359. </el-option>
  360. </el-select>
  361. </div>
  362. </el-form-item>
  363. </el-col>
  364. </el-row>
  365. <el-form-item label="商品详情" prop="description">
  366. <editor ref="myeditor" @on-text-change="updateText" />
  367. </el-form-item>
  368. <el-row>
  369. <el-col :span="8">
  370. <el-form-item label="商品状态" prop="isShow">
  371. <el-radio-group v-model="form.isShow">
  372. <el-radio :label="item.dictValue" v-for="item in isShowOptions" >{{item.dictLabel}}</el-radio>
  373. </el-radio-group>
  374. </el-form-item>
  375. </el-col>
  376. <el-col :span="8">
  377. <el-form-item label="是否热卖" prop="isHot">
  378. <el-radio-group v-model="form.isHot">
  379. <el-radio :label="item.dictValue" v-for="item in isHotOptions" >{{item.dictLabel}}</el-radio>
  380. </el-radio-group>
  381. </el-form-item>
  382. </el-col>
  383. <el-col :span="8">
  384. <el-form-item label="猜你喜欢" prop="isGood">
  385. <el-radio-group v-model="form.isGood">
  386. <el-radio :label="item.dictValue" v-for="item in isGoodOptions" >{{item.dictLabel}}</el-radio>
  387. </el-radio-group>
  388. </el-form-item>
  389. </el-col>
  390. </el-row>
  391. <el-row>
  392. <el-col :span="8">
  393. <el-form-item label="精品推荐" prop="isBest">
  394. <el-radio-group v-model="form.isBest">
  395. <el-radio :label="item.dictValue" v-for="item in isBestOptions" >{{item.dictLabel}}</el-radio>
  396. </el-radio-group>
  397. </el-form-item>
  398. </el-col>
  399. <el-col :span="8">
  400. <el-form-item label="新品首发" prop="isNew">
  401. <el-radio-group v-model="form.isNew">
  402. <el-radio :label="item.dictValue" v-for="item in isNewOptions" >{{item.dictLabel}}</el-radio>
  403. </el-radio-group>
  404. </el-form-item>
  405. </el-col>
  406. <el-col :span="8">
  407. <el-form-item label="返还积分">
  408. <el-input-number v-model="form.giveIntegral" :min="0" placeholder="请输入积分" />
  409. </el-form-item>
  410. </el-col>
  411. </el-row>
  412. <el-row>
  413. <el-col :span="8">
  414. <el-form-item label="商城展示" prop="isDisplay">
  415. <el-radio-group v-model="form.isDisplay">
  416. <el-radio :label="item.dictValue" v-for="item in isDisplayOptions" >{{item.dictLabel}}</el-radio>
  417. </el-radio-group>
  418. </el-form-item>
  419. </el-col>
  420. <el-col :span="8">
  421. <el-form-item label="排序" prop="sort">
  422. <el-input-number :min="0" v-model="form.sort" placeholder="请输入排序" />
  423. </el-form-item>
  424. </el-col>
  425. <el-col :span="8">
  426. <el-form-item label="销量" prop="sales">
  427. <el-input-number :min="0" v-model="form.sales" placeholder="请输入销量" />
  428. </el-form-item>
  429. </el-col>
  430. </el-row>
  431. <el-form-item label="推广分类" prop="tuiCateId">
  432. <el-select style="width: 240px" v-model="form.tuiCateId" placeholder="请选择推广分类" clearable size="small" >
  433. <el-option
  434. v-for="item in productTuiCateOptions"
  435. :key="item.dictValue"
  436. :label="item.dictLabel"
  437. :value="item.dictValue"
  438. />
  439. </el-select>
  440. </el-form-item>
  441. <el-form-item label="商品类型" prop="productType">
  442. <el-select style="width: 240px" v-model="form.productType" placeholder="请选择商品类型" clearable size="small" >
  443. <el-option
  444. v-for="item in productTypeOptions"
  445. :key="item.dictValue"
  446. :label="item.dictLabel"
  447. :value="item.dictValue"
  448. />
  449. </el-select>
  450. </el-form-item>
  451. <el-form-item label="国药准字" v-if="form.productType==2" prop="prescribeCode">
  452. <el-input v-model="form.prescribeCode" placeholder="请输入国药准字" />
  453. </el-form-item>
  454. <el-form-item label="规格" v-if="form.productType==2" prop="prescribeSpec">
  455. <el-input v-model="form.prescribeSpec" placeholder="请输入规格" />
  456. </el-form-item>
  457. <el-form-item label="生产厂家" v-if="form.productType==2" prop="prescribeFactory">
  458. <el-input v-model="form.prescribeFactory" placeholder="请输入生产厂家" />
  459. </el-form-item>
  460. <el-form-item label="处方名" v-if="form.productType==2" prop="prescribeName">
  461. <el-input v-model="form.prescribeName" placeholder="请输入处方名" />
  462. </el-form-item>
  463. </el-form>
  464. <div slot="footer" class="dialog-footer">
  465. <el-button type="primary" @click="submitForm">确 定</el-button>
  466. <el-button @click="cancel">取 消</el-button>
  467. </div>
  468. </el-dialog>
  469. </div>
  470. </template>
  471. <script>
  472. import {genFormatAttr, listStoreProduct, getStoreProduct, delStoreProduct, addOrEdit, exportStoreProduct } from "@/api/store/storeProduct";
  473. import { getAllStoreProductCategory } from "@/api/store/storeProductCategory";
  474. import { getAllStoreProductRule } from "@/api/store/storeProductRule";
  475. import { getAllShippingTemplates } from "@/api/store/shippingTemplates";
  476. import Treeselect from "@riophae/vue-treeselect";
  477. import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  478. import Editor from '@/components/Editor/wang';
  479. import Material from '@/components/Material'
  480. import singleImg from '@/components/Material/single'
  481. export default {
  482. name: "StoreProduct",
  483. components: {
  484. Treeselect,
  485. Editor,
  486. Material,
  487. singleImg,
  488. },
  489. watch: {
  490. imageArr: function(val) {
  491. this.form.image = val.join(',')
  492. },
  493. photoArr: function(val) {
  494. this.form.sliderImage = val.join(',')
  495. }
  496. },
  497. data() {
  498. return {
  499. productTuiCateOptions:[],
  500. showIput: false,
  501. createBnt:true,
  502. // 规格数据
  503. formDynamic: {
  504. attrsName: '',
  505. attrsVal: ''
  506. },
  507. isBtn: false,
  508. columns: [],
  509. attrs:[],
  510. templateList:[],
  511. ruleList:[],
  512. // 多规格表格data
  513. manyFormValidate: [],
  514. // 单规格表格data
  515. oneFormValidate: [
  516. {
  517. image: '',
  518. price: 0,
  519. cost: 0,
  520. agentPrice: 0,
  521. otPrice: 0,
  522. stock: 0,
  523. barCode: '',
  524. weight: 0,
  525. volume: 0,
  526. integral: 0
  527. }
  528. ],
  529. photoArr:[],
  530. imageArr:[],
  531. activeName:"1",
  532. productTypeOptions:[],
  533. isDisplayOptions:[],
  534. isGoodOptions:[],
  535. isNewOptions:[],
  536. isBestOptions:[],
  537. isHotOptions:[],
  538. isShowOptions:[],
  539. categoryOptions:[],
  540. // 遮罩层
  541. loading: true,
  542. // 选中数组
  543. ids: [],
  544. // 非单个禁用
  545. single: true,
  546. // 非多个禁用
  547. multiple: true,
  548. // 显示搜索条件
  549. showSearch: true,
  550. // 总条数
  551. total: 0,
  552. // 商品表格数据
  553. storeProductList: [],
  554. // 弹出层标题
  555. title: "",
  556. // 是否显示弹出层
  557. open: false,
  558. // 查询参数
  559. queryParams: {
  560. pageNum: 1,
  561. pageSize: 10,
  562. productName: null,
  563. productType: null,
  564. isShow: "1",
  565. },
  566. // 表单参数
  567. form: {},
  568. // 表单校验
  569. rules: {
  570. image: [
  571. { required: true, message: "商品图片不能为空", trigger: "blur" }
  572. ],
  573. sliderImage: [
  574. { required: true, message: "轮播图不能为空", trigger: "blur" }
  575. ],
  576. productName: [
  577. { required: true, message: "商品名称不能为空", trigger: "blur" }
  578. ],
  579. productInfo: [
  580. { required: true, message: "商品简介不能为空", trigger: "blur" }
  581. ],
  582. unitName: [
  583. { required: true, message: "单位名不能为空", trigger: "blur" }
  584. ],
  585. keyword: [
  586. { required: true, message: "关键字不能为空", trigger: "blur" }
  587. ],
  588. cateId: [
  589. { required: true, message: "分类id不能为空", trigger: "blur" }
  590. ],
  591. price: [
  592. { required: true, message: "商品价格不能为空", trigger: "blur" }
  593. ],
  594. prescribeCode: [
  595. { required: true, message: "国药准字不能为空", trigger: "blur" }
  596. ],
  597. prescribeSpec: [
  598. { required: true, message: "规格不能为空", trigger: "blur" }
  599. ],
  600. prescribeFactory: [
  601. { required: true, message: "生产厂家不能为空", trigger: "blur" }
  602. ],
  603. prescribeName: [
  604. { required: true, message: "处方药不能为空", trigger: "blur" }
  605. ],
  606. }
  607. };
  608. },
  609. created() {
  610. this.getDicts("store_product_tui_cate").then((response) => {
  611. this.productTuiCateOptions = response.data;
  612. });
  613. this.getDicts("store_product_enable").then((response) => {
  614. this.isNewOptions = response.data;
  615. this.isBestOptions = response.data;
  616. this.isHotOptions = response.data;
  617. this.isGoodOptions=response.data;
  618. this.isDisplayOptions=response.data;
  619. });
  620. this.getDicts("store_product_type").then((response) => {
  621. this.productTypeOptions = response.data;
  622. });
  623. this.getDicts("store_product_is_show").then((response) => {
  624. this.isShowOptions = response.data;
  625. });
  626. getAllShippingTemplates().then(response => {
  627. this.templateList =response.data;
  628. });
  629. getAllStoreProductRule().then(response => {
  630. this.ruleList =response.data;
  631. });
  632. this.getTreeselect();
  633. this.getList();
  634. },
  635. methods: {
  636. // 删除表格中的属性
  637. delAttrTable (index) {
  638. this.manyFormValidate.splice(index, 1);
  639. },
  640. addBtn () {
  641. this.clearAttr();
  642. this.createBnt = false;
  643. this.showIput = true;
  644. },
  645. //生成SKU
  646. generate () {
  647. genFormatAttr(this.form.productId, { attrs: this.attrs }).then(res => {
  648. if(this.form.specType === 0){
  649. this.oneFormValidate = res.value;
  650. this.form.header = res.header;
  651. let header = res.header;
  652. header.pop();
  653. this.oneFormValidate.map((item) => {
  654. if(this.imageArr.length>0){
  655. item.image = this.imageArr[0]
  656. }
  657. });
  658. }else if(this.form.specType === 1) {
  659. this.manyFormValidate = res.value;
  660. let headerdel = {
  661. title: '操作',
  662. slot: 'action',
  663. fixed: 'right',
  664. width: 220
  665. };
  666. res.header.push(headerdel);
  667. this.form.header = res.header;
  668. let header = res.header;
  669. header.pop();
  670. // this.manyFormValidate.map((item) => {
  671. // if(this.imageArr.length>0){
  672. // item.image = this.imageArr[0]
  673. // }
  674. // });
  675. }
  676. }).catch(res => {
  677. })
  678. },
  679. // 取消添加新规格
  680. closeAttrName () {
  681. this.showIput = false;
  682. this.createBnt = true;
  683. },
  684. clearAttr () {
  685. this.formDynamic.attrsName = '';
  686. this.formDynamic.attrsVal = '';
  687. },
  688. // 删除规格
  689. handleRemoveRole (index) {
  690. this.attrs.splice(index, 1);
  691. this.manyFormValidate.splice(index, 1);
  692. },
  693. // 删除属性
  694. handleRemove2 (item, index) {
  695. item.splice(index, 1);
  696. },
  697. // 添加规则名称
  698. createAttrName () {
  699. if (this.formDynamic.attrsName && this.formDynamic.attrsVal) {
  700. let data = {
  701. value: this.formDynamic.attrsName,
  702. detail: [
  703. this.formDynamic.attrsVal
  704. ]
  705. };
  706. this.attrs.push(data);
  707. var hash = {};
  708. this.attrs = this.attrs.reduce(function (item, next) {
  709. hash[next.value] ? '' : hash[next.value] = true && item.push(next);
  710. return item
  711. }, [])
  712. this.clearAttr();
  713. this.showIput = false;
  714. this.createBnt = true;
  715. } else {
  716. this.$message.warning('请添加完整的规格!');
  717. }
  718. },
  719. // 添加属性
  720. createAttr (num, idx) {
  721. if (num) {
  722. this.attrs[idx].detail.push(num);
  723. var hash = {};
  724. this.attrs[idx].detail = this.attrs[idx].detail.reduce(function (item, next) {
  725. hash[next] ? '' : hash[next] = true && item.push(next);
  726. return item
  727. }, [])
  728. } else {
  729. this.$message.warning('请添加属性!');
  730. }
  731. },
  732. confirm () {
  733. let that = this;
  734. that.createBnt = true;
  735. if (that.form.selectRule==null||that.form.selectRule.trim().length <= 0) {
  736. return this.$message({
  737. message:'请选择属性',
  738. type: 'error'
  739. });
  740. }
  741. that.ruleList.forEach(function (item, index) {
  742. if (item.ruleName === that.form.selectRule) {
  743. that.attrs =JSON.parse( item.ruleValue);
  744. }
  745. });
  746. },
  747. updateText(text){
  748. this.form.description=text
  749. },
  750. handleClick(tab, event) {
  751. this.queryParams.isShow=tab.name;
  752. this.getList();
  753. },
  754. /** 转换商品分类数据结构 */
  755. normalizer(node) {
  756. if (node.children && !node.children.length) {
  757. delete node.children;
  758. }
  759. return {
  760. id: node.cateId,
  761. label: node.cateName,
  762. children: node.children
  763. };
  764. },
  765. getTreeselect() {
  766. getAllStoreProductCategory().then(response => {
  767. this.categoryOptions = [];
  768. const data = this.handleTree(response.data, "cateId", "pid");
  769. this.categoryOptions=data;
  770. });
  771. },
  772. /** 查询商品列表 */
  773. getList() {
  774. this.loading = true;
  775. listStoreProduct(this.queryParams).then(response => {
  776. this.storeProductList = response.rows;
  777. this.total = response.total;
  778. this.loading = false;
  779. });
  780. },
  781. // 取消按钮
  782. cancel() {
  783. this.open = false;
  784. this.reset();
  785. },
  786. // 表单重置
  787. reset() {
  788. this.form = {
  789. productId: 0,
  790. image: null,
  791. sliderImage: null,
  792. productName: null,
  793. productInfo: null,
  794. keyword: null,
  795. barCode: null,
  796. cateId: null,
  797. price: null,
  798. vipPrice: null,
  799. otPrice: null,
  800. postage: null,
  801. unitName: null,
  802. sort: null,
  803. sales: null,
  804. stock: null,
  805. isShow: "0",
  806. isHot: "0",
  807. isBenefit: "0",
  808. isBest: "0",
  809. isNew: "0",
  810. description: null,
  811. createTime: null,
  812. updateTime: null,
  813. isPostage: null,
  814. isDel: null,
  815. giveIntegral: null,
  816. cost: null,
  817. isGood: "0",
  818. browse: null,
  819. codePath: null,
  820. tempId: "",
  821. specType: 0,
  822. isIntegral: null,
  823. integral: null,
  824. productType: "1",
  825. prescribeCode: null,
  826. prescribeSpec: null,
  827. prescribeFactory: null,
  828. prescribeName: null,
  829. isDisplay:"1"
  830. };
  831. this.resetForm("form");
  832. this.oneFormValidate = [
  833. {
  834. image: '',
  835. price: 0,
  836. agentPrice: 0,
  837. cost: 0,
  838. otPrice: 0,
  839. stock: 0,
  840. barCode: '',
  841. weight: 0,
  842. volume: 0,
  843. integral: 0,
  844. brokerage:0,
  845. brokerageTwo:0
  846. }
  847. ]
  848. this.attrs=[];
  849. this.photoArr=[];
  850. this.imageArr=[];
  851. },
  852. /** 搜索按钮操作 */
  853. handleQuery() {
  854. this.queryParams.pageNum = 1;
  855. this.getList();
  856. },
  857. /** 重置按钮操作 */
  858. resetQuery() {
  859. this.resetForm("queryForm");
  860. this.handleQuery();
  861. },
  862. // 多选框选中数据
  863. handleSelectionChange(selection) {
  864. this.ids = selection.map(item => item.productId)
  865. this.single = selection.length!==1
  866. this.multiple = !selection.length
  867. },
  868. /** 新增按钮操作 */
  869. handleAdd() {
  870. this.reset();
  871. this.open = true;
  872. this.title = "添加商品";
  873. setTimeout(() => {
  874. this.$refs.myeditor.setText("");
  875. }, 500);
  876. },
  877. /** 修改按钮操作 */
  878. handleUpdate(row) {
  879. var that=this;
  880. this.reset();
  881. const productId = row.productId || this.ids
  882. getStoreProduct(productId).then(response => {
  883. this.form = response.data;
  884. this.form.isShow = response.data.isShow.toString();
  885. this.form.isHot = response.data.isHot.toString();
  886. this.form.isGood = response.data.isGood.toString();
  887. this.form.isBest = response.data.isBest.toString();
  888. this.form.isNew = response.data.isNew.toString();
  889. this.form.productType = response.data.productType.toString();
  890. this.form.isDisplay = response.data.isDisplay.toString();
  891. if(this.form.tuiCateId!=null){
  892. this.form.tuiCateId = response.data.tuiCateId.toString();
  893. }
  894. //组装attrs数据
  895. if(response.attrs!=null){
  896. this.attrs=[];
  897. response.attrs.forEach(function (item, index) {
  898. var data={value:item.attrName,detail:item.attrValues.split(',')}
  899. that.attrs.push(data);
  900. });
  901. }
  902. setTimeout(() => {
  903. that.generate();
  904. }, 200);
  905. if(this.form.specType === 0){
  906. that.manyFormValidate = [];
  907. }else {
  908. that.createBnt = true;
  909. that.oneFormValidate = [
  910. {
  911. image: '',
  912. price: 0,
  913. agentPrice: 0,
  914. cost: 0,
  915. otPrice: 0,
  916. stock: 0,
  917. barCode: '',
  918. weight: 0,
  919. volume: 0,
  920. integral: 0,
  921. brokerage:0,
  922. brokerageTwo:0
  923. }
  924. ]
  925. }
  926. setTimeout(() => {
  927. if(this.form.description==null){
  928. this.$refs.myeditor.setText("");
  929. }
  930. else{
  931. this.$refs.myeditor.setText(this.form.description);
  932. }
  933. }, 200);
  934. if(this.form.image!=null){
  935. this.imageArr=this.form.image.split(",");
  936. }
  937. if(this.form.sliderImage!=null){
  938. this.photoArr=this.form.sliderImage.split(",");
  939. }
  940. console.log(this.oneFormValidate)
  941. this.open = true;
  942. this.title = "修改商品";
  943. });
  944. },
  945. /** 提交按钮 */
  946. submitForm() {
  947. this.$refs["form"].validate(valid => {
  948. if (valid) {
  949. if(this.form.specType ===0 ){
  950. this.form.items = [];
  951. this.form.values = this.oneFormValidate;
  952. }else{
  953. this.form.items = this.attrs;
  954. this.form.values = this.manyFormValidate;
  955. }
  956. if(this.form.specType === 1 && this.manyFormValidate.length===0){
  957. return this.$message.warning('请点击生成规格!');
  958. }
  959. addOrEdit(this.form).then(response => {
  960. if (response.code === 200) {
  961. this.msgSuccess("修改成功");
  962. this.open = false;
  963. this.getList();
  964. }
  965. });
  966. }
  967. });
  968. },
  969. /** 删除按钮操作 */
  970. handleDelete(row) {
  971. const productIds = row.productId || this.ids;
  972. this.$confirm('是否确认删除商品编号为"' + productIds + '"的数据项?', "警告", {
  973. confirmButtonText: "确定",
  974. cancelButtonText: "取消",
  975. type: "warning"
  976. }).then(function() {
  977. return delStoreProduct(productIds);
  978. }).then(() => {
  979. this.getList();
  980. this.msgSuccess("删除成功");
  981. }).catch(function() {});
  982. },
  983. /** 导出按钮操作 */
  984. handleExport() {
  985. const queryParams = this.queryParams;
  986. this.$confirm('是否确认导出所有商品数据项?', "警告", {
  987. confirmButtonText: "确定",
  988. cancelButtonText: "取消",
  989. type: "warning"
  990. }).then(function() {
  991. return exportStoreProduct(queryParams);
  992. }).then(response => {
  993. this.download(response.msg);
  994. }).catch(function() {});
  995. }
  996. }
  997. };
  998. </script>