form.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <template>
  2. <el-drawer :title="titleMap[mode]" :append-to-body="true" v-model="visible" :size="1000" destroy-on-close :close-on-click-modal="false" @closed="$emit('closed')" :with-header="false">
  3. <el-container class="flex-column" v-loading="loading">
  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. <fieldset>
  17. <legend><el-tag>基础信息</el-tag></legend>
  18. <el-row :gutter="15">
  19. <el-col :span="24">
  20. <el-form-item label="所属店铺" prop="store_id">
  21. <el-input v-model="formData.store_id" placeholder="所属店铺" clearable readonly :style="{ width: '100%' }" @click="selectUser">
  22. <template #append>
  23. <el-tooltip
  24. effect="dark"
  25. content="点这里,清除选择"
  26. placement="top-start"
  27. >
  28. <div class="remove-a" @click="clearUser">清除</div>
  29. </el-tooltip>
  30. </template>
  31. </el-input>
  32. </el-form-item>
  33. </el-col>
  34. <el-col :span="12">
  35. <el-form-item label="商品标题" prop="product_name">
  36. <el-input v-model="formData.product_name" clearable placeholder="请输入"></el-input>
  37. <div class="el-form-item-msg"></div>
  38. </el-form-item>
  39. </el-col>
  40. <el-col :span="12">
  41. <el-form-item label="快递面单名称" prop="express_name">
  42. <el-input v-model="formData.express_name" clearable placeholder="请输入"></el-input>
  43. <div class="el-form-item-msg">不填写默认使用商品标题名称</div>
  44. </el-form-item>
  45. </el-col>
  46. <el-col :span="8">
  47. <el-form-item label="来客团单ID" prop="out_id">
  48. <el-input v-model="formData.out_id" clearable placeholder="请输入"></el-input>
  49. <div class="el-form-item-msg"></div>
  50. </el-form-item>
  51. </el-col>
  52. <el-col :span="8">
  53. <el-form-item label="商品价格" prop="product_price">
  54. <el-input v-model="formData.product_price" clearable placeholder="请输入">
  55. <template #append>元</template>
  56. </el-input>
  57. <div class="el-form-item-msg"></div>
  58. </el-form-item>
  59. </el-col>
  60. <el-col :span="8">
  61. <el-form-item label="商品划线价格" prop="product_origin">
  62. <el-input v-model="formData.product_origin" clearable placeholder="请输入">
  63. <template #append>元</template>
  64. </el-input>
  65. <div class="el-form-item-msg"></div>
  66. </el-form-item>
  67. </el-col>
  68. <el-col :span="24">
  69. <el-form-item label="商品图片" prop="product_img">
  70. <sc-upload v-model="formData.product_img" tip="最多上传100个文件,单个文件不要超过10M,请上传图像格式文件"></sc-upload>
  71. <div class="el-form-item-msg">选填</div>
  72. </el-form-item>
  73. </el-col>
  74. </el-row>
  75. </fieldset>
  76. <fieldset>
  77. <legend><el-tag>商品附加规格</el-tag></legend>
  78. <el-button type="primary" size="small" @click="addSpecs" v-if="specs.length<5">添加规格分组</el-button>
  79. <div class="specs" v-for="(item,indx) in specs" :key="indx">
  80. <div class="specs-header">
  81. <div class="specs-left">
  82. <el-input v-model="item.name" placeholder="组名称" clearable>
  83. <template #prepend>组名称</template>
  84. </el-input>
  85. <el-select v-model="item.num" clearable placeholder="请选择数量" v-if="item.list.length > 1">
  86. <el-option :value="len" :label="item.list.length+'选'+len" v-for="len in item.list.length"></el-option>
  87. </el-select>
  88. </div>
  89. <div class="specs-right">
  90. <el-button type="primary" @click="addItem(indx)">增加</el-button>
  91. <el-button type="danger" @click="removeSpec(indx)">删除</el-button>
  92. </div>
  93. </div>
  94. <div class="specs-body">
  95. <div class="body-item" v-for="(its,ind) in item.list" :key="ind">
  96. <el-input placeholder="输入规格属性名" v-model="its.name" clearable>
  97. <template #append>
  98. <el-popconfirm title="确定删除吗?" @click="removeItem(indx,ind)">
  99. <template #reference>
  100. <el-button type="danger" icon="el-icon-delete" size="small"></el-button>
  101. </template>
  102. </el-popconfirm>
  103. </template>
  104. </el-input>
  105. </div>
  106. </div>
  107. </div>
  108. </fieldset>
  109. </el-form>
  110. </el-main>
  111. <el-footer style="text-align: right;">
  112. <el-button @click="visible=false" >取 消</el-button>
  113. <el-button v-if="mode!='show'" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
  114. </el-footer>
  115. </el-container>
  116. </el-drawer>
  117. <storeData ref="storeData" :multiple="false" @success="handleSuccess"></storeData>
  118. </template>
  119. <script>
  120. import storeData from "@/views/manage/components/store";
  121. export default {
  122. components: {
  123. storeData
  124. },
  125. data(){
  126. return {
  127. loading: false,
  128. mode:"add",
  129. titleMap:{
  130. add:"新增商品",
  131. edit:"编辑商品"
  132. },
  133. visible: false,
  134. isSaveing: false,
  135. specs:[],
  136. formData:{},
  137. userInfo:{},
  138. rules:{
  139. store_id: [
  140. {required: true, message: '请选择'}
  141. ],
  142. out_id: [
  143. {required: true, message: '请输入'}
  144. ],
  145. product_name: [
  146. {required: true, message: '请输入'}
  147. ],
  148. product_price: [
  149. {required: true, message: '请输入'}
  150. ],
  151. product_origin: [
  152. {required: true, message: '请输入'}
  153. ],
  154. }
  155. }
  156. },
  157. methods:{
  158. addSpecs(){
  159. if (this.specs.length >= 5) {
  160. return this.$message.error("最多只能添加三组规格")
  161. }
  162. this.specs.push({"name":"","num":1,"list":[ {"name":"","check":true} ]});
  163. },
  164. addItem(index){
  165. if (this.specs[index].list.length >= 20) {
  166. return this.$message.error("最多只能添加20个")
  167. }
  168. this.specs[index].list.push({"name":"","check":true})
  169. },
  170. removeSpec(index){
  171. this.specs.splice(index,1)
  172. },
  173. removeItem(index,sub){
  174. this.specs[index].list.splice(sub,1)
  175. },
  176. handleSuccess(data){
  177. this.formData.store_id = data.store_id;
  178. },
  179. clearUser(){
  180. this.formData.store_id = "";
  181. },
  182. selectUser(){
  183. this.$nextTick(() => {
  184. this.$refs.storeData.open("add",this.userInfo.agent_id)
  185. })
  186. },
  187. open(mode = 'add'){
  188. this.mode = mode;
  189. this.visible = true;
  190. var userInfo = this.$TOOL.data.get("USER_INFO");
  191. this.userInfo = userInfo;
  192. return this
  193. },
  194. //表单注入数据
  195. setData(data){
  196. this.formData = JSON.parse(JSON.stringify(data));
  197. if (this.mode == 'edit') {
  198. this.specs = data.data_specs;
  199. }
  200. },
  201. async submit(){
  202. var validate = await this.$refs.dialogForm.validate().catch(()=>{});
  203. if(!validate){ return false }
  204. this.isSaveing = true;
  205. let submitData = JSON.parse(JSON.stringify(this.formData));
  206. if (this.specs.length > 0) {
  207. submitData.data_specs = JSON.stringify(this.specs);
  208. }
  209. var resp = await this.$API.goods.save.post(submitData);
  210. this.isSaveing = false;
  211. if (resp.code == 0) {
  212. return this.$message.error(resp.msg);
  213. }
  214. this.$message.success(resp.msg);
  215. this.visible = false;
  216. this.formData = {};
  217. this.specs = [];
  218. this.submitState = false;
  219. this.$emit("success");
  220. }
  221. }
  222. }
  223. </script>
  224. <style>
  225. .specs{margin-top: 15px;background-color: #f8f8f8;}
  226. .specs-header{
  227. display: flex;
  228. margin-bottom: 10px;
  229. border-bottom: 1px solid #f8f8f8;
  230. background-color: #ddd;
  231. padding: 10px;
  232. }
  233. .specs-header .specs-left{
  234. display: flex;
  235. align-items: center;
  236. gap: 10px;
  237. }
  238. .specs-header .specs-right{
  239. display: flex;
  240. margin-left: auto;
  241. margin-right: 0;
  242. }
  243. .specs-body{display: flex;align-items: center;gap: 10px;padding: 10px;flex-direction: row;flex-wrap: wrap;}
  244. .specs-body .body-item{width: calc(25% - 10px);}
  245. </style>