audit.vue 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  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="storeName">
  5. <el-input
  6. v-model="queryParams.storeName"
  7. placeholder="请输入店铺名称"
  8. clearable
  9. size="small"
  10. @keyup.enter.native="handleQuery"
  11. />
  12. </el-form-item>
  13. <el-form-item label="地址" prop="address">
  14. <el-input
  15. v-model="queryParams.address"
  16. placeholder="请输入地址"
  17. clearable
  18. size="small"
  19. @keyup.enter.native="handleQuery"
  20. />
  21. </el-form-item>
  22. <el-form-item label="店铺电话" prop="phone">
  23. <el-input
  24. v-model="queryParams.phone"
  25. placeholder="请输入店铺电话"
  26. clearable
  27. size="small"
  28. @keyup.enter.native="handleQuery"
  29. />
  30. </el-form-item>
  31. <el-form-item label="状态" prop="status">
  32. <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
  33. <el-option
  34. v-for="dict in statusOptions"
  35. :key="dict.dictValue"
  36. :label="dict.dictLabel"
  37. :value="dict.dictValue"
  38. />
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item label="登录帐号" prop="account">
  42. <el-input
  43. v-model="queryParams.account"
  44. placeholder="请输入登录帐号"
  45. clearable
  46. size="small"
  47. @keyup.enter.native="handleQuery"
  48. />
  49. </el-form-item>
  50. <el-form-item label="店铺Id" prop="storeSeq">
  51. <el-input
  52. v-model="queryParams.storeSeq"
  53. placeholder="请输入店铺Id"
  54. clearable
  55. size="small"
  56. @keyup.enter.native="handleQuery"
  57. />
  58. </el-form-item>
  59. <el-form-item label="商家Id" prop="merchantId">
  60. <el-input
  61. v-model="queryParams.merchantId"
  62. placeholder="请输入商家Id"
  63. clearable
  64. size="small"
  65. @keyup.enter.native="handleQuery"
  66. />
  67. </el-form-item>
  68. <el-form-item>
  69. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  70. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  71. </el-form-item>
  72. </el-form>
  73. <el-row :gutter="10" class="mb8">
  74. <el-col :span="1.5">
  75. <el-button
  76. type="warning"
  77. plain
  78. icon="el-icon-download"
  79. size="mini"
  80. :loading="exportLoading"
  81. @click="handleExport"
  82. v-hasPermi="['his:store:export']"
  83. >导出</el-button>
  84. </el-col>
  85. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  86. </el-row>
  87. <el-tabs type="card" v-model="queryParams.isAudit" @tab-click="handleClickX">
  88. <el-tab-pane v-for="(item,index) in isAuditOptions" :label="item.dictLabel" :name="item.dictValue"></el-tab-pane>
  89. </el-tabs>
  90. <el-table v-loading="loading" border :data="storeList" @selection-change="handleSelectionChange">
  91. <el-table-column type="selection" width="55" align="center" />
  92. <!-- <el-table-column label="店铺id" align="center" prop="storeId" width="120px"/>-->
  93. <el-table-column label="商家ID" align="center" prop="merchantId" width="150px"/>
  94. <el-table-column label="店铺ID" align="center" prop="storeSeq" width="150px"/>
  95. <el-table-column label="店铺名称" align="center" prop="storeName" width="120px"/>
  96. <el-table-column label="店铺LOGO" align="center" prop="logoUrl" width="100px">
  97. <template slot-scope="scope">
  98. <el-popover
  99. placement="right"
  100. title=""
  101. trigger="hover">
  102. <img slot="reference" :src="scope.row.logoUrl" width="80px">
  103. <img :src="scope.row.logoUrl" style="max-width: 150px;">
  104. </el-popover>
  105. </template>
  106. </el-table-column>
  107. <el-table-column label="地址" align="center" prop="enterpriseAddress" width="200px"/>
  108. <el-table-column label="店铺电话" align="center" prop="phone" width="120px"/>
  109. <!-- <el-table-column label="资质证书" align="center" prop="licenseImages" width="100px">
  110. <template slot-scope="scope">
  111. <el-popover
  112. placement="right"
  113. title=""
  114. trigger="hover">
  115. <img slot="reference" :src="scope.row.licenseImages" width="80px">
  116. <img :src="scope.row.licenseImages" style="max-width: 150px;">
  117. </el-popover>
  118. </template>
  119. </el-table-column>-->
  120. <el-table-column label="审核状态" align="center" prop="isAudit">
  121. <template slot-scope="scope">
  122. <dict-tag :options="isAuditOptions" :value="scope.row.isAudit"/>
  123. </template>
  124. </el-table-column>
  125. <el-table-column label="商品总数" align="center" prop="productCount" />
  126. <el-table-column label="状态" align="center" prop="status">
  127. <template slot-scope="scope">
  128. <dict-tag :options="statusOptions" :value="scope.row.status"/>
  129. </template>
  130. </el-table-column>
  131. <el-table-column label="销量" align="center" prop="salesCount" />
  132. <el-table-column label="余额" align="center" prop="balance" />
  133. <el-table-column label="累计金额" align="center" prop="totalMoney" />
  134. <el-table-column label="登录帐号" align="center" prop="account" width="150px" />
  135. <el-table-column label="创建时间" align="center" prop="createTime" width="150px"/>
  136. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="130px" v-if="medicalMallConfig.isAudit">
  137. <template slot-scope="scope">
  138. <el-button
  139. size="mini"
  140. type="text"
  141. icon="el-icon-s-promotion"
  142. @click="handledetails(scope.row)">
  143. <span v-if="scope.row.isAudit===0">审核</span>
  144. <span v-else>详情</span>
  145. </el-button>
  146. </template>
  147. </el-table-column>
  148. </el-table>
  149. <pagination
  150. v-show="total>0"
  151. :total="total"
  152. :page.sync="queryParams.pageNum"
  153. :limit.sync="queryParams.pageSize"
  154. @pagination="getList"
  155. />
  156. <!-- 使用StoreDialog组件 -->
  157. <StoreDialog
  158. :visible.sync="open"
  159. mode="audit"
  160. :form-data="form"
  161. :audit-logs="auditLogs"
  162. :medicalMallConfig="medicalMallConfig"
  163. @audit="handleAuditSubmit"
  164. @close="handleDialogClose"
  165. >
  166. <template #form="{ form: dialogForm, formDisabled }">
  167. <el-form :model="dialogForm" label-width="120px" label-position="top" :disabled="formDisabled">
  168. <el-divider content-position="left">基础信息</el-divider>
  169. <el-row>
  170. <el-col :span="12">
  171. <el-form-item label="店铺名称">
  172. <el-input v-model="dialogForm.storeName" placeholder="请输入店铺名称" />
  173. </el-form-item>
  174. </el-col>
  175. <el-col :span="12">
  176. <el-form-item label="电话">
  177. <el-input v-model="dialogForm.phone" placeholder="请输入店铺电话" />
  178. </el-form-item>
  179. </el-col>
  180. </el-row>
  181. <el-form-item label="企业全称">
  182. <el-input v-model="dialogForm.fullName" placeholder="请输入企业全称" />
  183. </el-form-item>
  184. <el-row>
  185. <el-col :span="12">
  186. <el-form-item label="店铺LOGO">
  187. <img v-if="dialogForm.logoUrl" :src="dialogForm.logoUrl" width="200px">
  188. </el-form-item>
  189. </el-col>
  190. </el-row>
  191. <el-row>
  192. <el-col :span="24">
  193. <el-form-item label="店铺介绍">
  194. <el-input v-model="dialogForm.descs" type="textarea" :rows="3" placeholder="请输入店铺介绍" maxlength="100" />
  195. </el-form-item>
  196. </el-col>
  197. </el-row>
  198. <el-row>
  199. <el-col :span="12">
  200. <el-form-item label="所属城市">
  201. <el-input v-model="dialogForm.address" placeholder="请输入地址" />
  202. </el-form-item>
  203. </el-col>
  204. <el-col :span="12">
  205. <el-form-item label="地址" prop="enterpriseAddress">
  206. <el-input v-model="dialogForm.enterpriseAddress" placeholder="请输入地址"/>
  207. </el-form-item>
  208. </el-col>
  209. </el-row>
  210. <el-row>
  211. <el-col :span="12">
  212. <el-form-item label="法人姓名">
  213. <el-input v-model="dialogForm.legalPersonName" placeholder="请输入法人姓名" />
  214. </el-form-item>
  215. </el-col>
  216. <el-col :span="12">
  217. <el-form-item label="统一社会信用代码">
  218. <el-input v-model="dialogForm.unifiedSocialCreditCode" placeholder="请输入统一社会信用代码" />
  219. </el-form-item>
  220. </el-col>
  221. <el-col :span="12">
  222. <el-form-item label="商家ID">
  223. <el-input v-model="dialogForm.merchantId" />
  224. </el-form-item>
  225. </el-col>
  226. </el-row>
  227. <el-form-item label="营业范围">
  228. <el-input v-model="dialogForm.businessScope" type="textarea" placeholder="请输入营业范围" />
  229. </el-form-item>
  230. <!-- 证书信息 -->
  231. <el-divider content-position="left">资质证书信息</el-divider>
  232. <el-row>
  233. <el-col :span="12">
  234. <el-form-item label="营业执照">
  235. <el-image v-if="dialogForm.businessLicense" style="width: 200px" :src="dialogForm.businessLicense" :preview-src-list="[dialogForm.businessLicense]"></el-image>
  236. </el-form-item>
  237. <el-form-item label="营业执照编号" style="margin-left: 5px">
  238. <el-input v-model="dialogForm.businessCode" />
  239. </el-form-item>
  240. </el-col>
  241. <el-col :span="12">
  242. <el-form-item label="营业执照有效期">
  243. <span v-if="dialogForm.isBusinessLicensePermanent == 1">长期有效</span>
  244. <span v-else>{{dialogForm.businessLicenseExpireStart}} - {{dialogForm.businessLicenseExpireEnd}}</span>
  245. </el-form-item>
  246. </el-col>
  247. </el-row>
  248. <!-- 医疗相关证书 -->
  249. <div v-if="medicalMallConfig.isMedicalMall">
  250. <el-row>
  251. <el-col :span="12">
  252. <el-form-item label="药品经营许可证">
  253. <el-image v-if="dialogForm.drugLicense" style="width: 200px" :src="dialogForm.drugLicense" :preview-src-list="[dialogForm.drugLicense]"></el-image>
  254. <!-- 未上传图片时显示的默认图标 -->
  255. <div v-else class="no-image-placeholder">
  256. <span>用户未上传</span>
  257. </div>
  258. </el-form-item>
  259. <el-form-item label="药品经营许可证编号" style="margin-left: 5px">
  260. <el-input v-model="dialogForm.drugCode" />
  261. </el-form-item>
  262. </el-col>
  263. <el-col :sapn="24">
  264. <el-form-item label="药品经营许可证范围" prop="drugLicenseBusinessScope" style="margin-left: 5px">
  265. <el-input v-model="form.drugLicenseBusinessScope" placeholder="请输入药品经营许可证范围" type="textarea"/>
  266. </el-form-item>
  267. </el-col>
  268. <!-- 新增的单选框 -->
  269. <el-col :span="24">
  270. <el-form-item label="药品经营许可证范围是否包含" prop="drugScopeHasFrozen" style="margin-left: 5px">
  271. <el-radio-group v-model="form.drugScopeHasFrozen">
  272. <el-radio label="0">否</el-radio>
  273. <el-radio label="1">冷冻</el-radio>
  274. <el-radio label="2">冷藏</el-radio>
  275. <el-radio label="3">冷冻冷藏</el-radio>
  276. </el-radio-group>
  277. </el-form-item>
  278. </el-col>
  279. <!-- 结束 -->
  280. <el-col :span="12">
  281. <el-form-item label="药品经营许可证有效期">
  282. <span v-if="dialogForm.isDrugLicensePermanent == 1">长期有效</span>
  283. <span v-else>{{dialogForm.drugLicenseExpiryStart}} - {{dialogForm.drugLicenseExpiryEnd}}</span>
  284. </el-form-item>
  285. </el-col>
  286. </el-row>
  287. <el-row>
  288. <el-col :span="12">
  289. <el-form-item label="2类医疗器械备案证书">
  290. <el-image v-if="dialogForm.medicalDevice2" style="width: 200px" :src="dialogForm.medicalDevice2" :preview-src-list="[dialogForm.medicalDevice2]"></el-image>
  291. <!-- 未上传图片时显示的默认图标 -->
  292. <div v-else class="no-image-placeholder">
  293. <span>用户未上传</span>
  294. </div>
  295. </el-form-item>
  296. <el-form-item label="2类器械生产备案编号" style="margin-left: 5px">
  297. <el-input v-model="dialogForm.medicalDevice2Code" />
  298. </el-form-item>
  299. </el-col>
  300. <el-col :span="12">
  301. <el-form-item label="2类器械经营许可证是否长期有效" prop="isMedicalDevice2ExpiryPermanent">
  302. <el-switch
  303. @change="switchChange()"
  304. v-model="dialogForm.isMedicalDevice2ExpiryPermanent"
  305. :active-value="1"
  306. :inactive-value="0"
  307. active-color="#13ce66"
  308. inactive-color="#ff4949">
  309. </el-switch>
  310. </el-form-item>
  311. <el-form-item label="2类器械经营许可证有效期" prop="foodLicenseExpiry" v-if="dialogForm.isMedicalDevice2ExpiryPermanent != 1">
  312. <span>{{dialogForm.medicalDevice2ExpiryStart}} - {{dialogForm.medicalDevice2ExpiryEnd}}</span>
  313. </el-form-item>
  314. </el-col>
  315. <el-col :sapn="24">
  316. <el-form-item label="2类器械经营范围" prop="medicalDevice2BusinessScope" style="margin-left: 5px">
  317. <el-input v-model="form.medicalDevice2BusinessScope" placeholder="请输入2类器械经营范围" type="textarea"/>
  318. </el-form-item>
  319. </el-col>
  320. </el-row>
  321. <el-row>
  322. <el-col :span="12">
  323. <el-form-item label="3类器械经营许可证">
  324. <el-image v-if="dialogForm.medicalDevice3" style="width: 200px" :src="dialogForm.medicalDevice3" :preview-src-list="[dialogForm.medicalDevice3]"></el-image>
  325. <!-- 未上传图片时显示的默认图标 -->
  326. <div v-else class="no-image-placeholder">
  327. <span>用户未上传</span>
  328. </div>
  329. </el-form-item>
  330. <el-form-item label="3类器械生产备案编号" style="margin-left: 5px">
  331. <el-input v-model="dialogForm.medicalDevice3Code" />
  332. </el-form-item>
  333. </el-col>
  334. <el-col :span="12">
  335. <el-form-item label="3类器械经营许可证是否长期有效" prop="isMedicalDevice3ExpiryPermanent">
  336. <el-switch
  337. @change="switchChange()"
  338. v-model="dialogForm.isMedicalDevice3ExpiryPermanent"
  339. :active-value="1"
  340. :inactive-value="0"
  341. active-color="#13ce66"
  342. inactive-color="#ff4949">
  343. </el-switch>
  344. </el-form-item>
  345. <el-form-item label="3类器械经营许可证有效期" prop="foodLicenseExpiry" v-if="dialogForm.isMedicalDevice3ExpiryPermanent != 1">
  346. <span>{{dialogForm.medicalDevice3ExpiryStart}} - {{dialogForm.medicalDevice3ExpiryEnd}}</span>
  347. </el-form-item>
  348. </el-col>
  349. <el-col :sapn="24">
  350. <el-form-item label="3类器械经营范围" prop="medicalDevice3BusinessScope" style="margin-left: 5px">
  351. <el-input v-model="form.medicalDevice3BusinessScope" placeholder="请输入3类器械经营范围" type="textarea"/>
  352. </el-form-item>
  353. </el-col>
  354. </el-row>
  355. <el-row>
  356. <el-col :span="24">
  357. <el-form-item label="食品经营许可证/备案凭证上传">
  358. <!-- 图片容器(包含图片和删除按钮,仅在有图片时显示) -->
  359. <div v-if="dialogForm.foodLicense && dialogForm.foodLicense.length > 0" class="food-license-container">
  360. <div v-for="(url, index) in dialogForm.foodLicense" :key="index" class="food-license-item">
  361. <div class="avatar-wrapper">
  362. <img :src="url" class="avatar small-avatar" />
  363. <div class="button-group">
  364. <div class="preview-btn" @click.stop="previewImage(url)">
  365. <i class="el-icon-zoom-in"></i>
  366. </div>
  367. </div>
  368. </div>
  369. </div>
  370. </div>
  371. <!-- 未上传图片时显示的默认图标 -->
  372. <div v-else class="no-image-placeholder small-placeholder">
  373. <span>用户未上传</span>
  374. </div>
  375. </el-form-item>
  376. <el-form-item label="食品经营许可证/备案凭证编号" style="margin-left: 5px">
  377. <el-input v-model="dialogForm.foodCode" />
  378. </el-form-item>
  379. </el-col>
  380. <el-col :span="12">
  381. <el-form-item label="食品经营许可证/备案凭证是否长期有效" prop="isFoodLicenseExpiryPermanent">
  382. <el-switch
  383. @change="switchChange()"
  384. v-model="dialogForm.isFoodLicenseExpiryPermanent"
  385. :active-value="1"
  386. :inactive-value="0"
  387. active-color="#13ce66"
  388. inactive-color="#ff4949">
  389. </el-switch>
  390. </el-form-item>
  391. <el-form-item label="食品经营许可证/备案凭证有效期" prop="foodLicenseExpiry" v-if="dialogForm.isFoodLicenseExpiryPermanent != 1">
  392. <span>{{dialogForm.foodLicenseExpiryStart}} - {{dialogForm.foodLicenseExpiryEnd}}</span>
  393. </el-form-item>
  394. </el-col>
  395. <el-col :sapn="24">
  396. <el-form-item label="食品经营许可证/备案凭证经营范围" prop="foodLicenseBusinessScope">
  397. <el-input v-model="form.foodLicenseBusinessScope" placeholder="请输入食品经营许可证/备案凭证经营范围" type="textarea"/>
  398. </el-form-item>
  399. </el-col>
  400. </el-row>
  401. </div>
  402. <el-divider content-position="left">店铺配置信息</el-divider>
  403. <el-col :span="12">
  404. <el-form-item label="网销报告" prop="reportUrl">
  405. <el-upload
  406. class="upload-demo"
  407. :action="uploadUrl"
  408. :on-preview="handleFilePreview"
  409. :on-remove="handleRemove"
  410. :before-remove="beforeRemove"
  411. multiple
  412. :limit="1"
  413. :on-exceed="handleExceed"
  414. :file-list="reportFileList"
  415. :show-file-list="true"
  416. disabled>
  417. <el-button size="small" type="primary" disabled>点击上传</el-button>
  418. </el-upload>
  419. </el-form-item>
  420. </el-col>
  421. <el-col :span="12">
  422. <el-form-item label="备案" prop="filingUrl">
  423. <el-upload
  424. class="upload-demo"
  425. :action="uploadUrl"
  426. :on-preview="handleFilePreview"
  427. :on-remove="handleRemove"
  428. :before-remove="beforeRemove"
  429. multiple
  430. :limit="1"
  431. :on-exceed="handleExceed"
  432. :file-list="fileList"
  433. :show-file-list="true"
  434. disabled>
  435. <el-button size="small" type="primary" disabled>点击上传</el-button>
  436. </el-upload>
  437. </el-form-item>
  438. </el-col>
  439. <el-form-item label="退货地址">
  440. <el-input v-model="dialogForm.refundAddress" />
  441. </el-form-item>
  442. <el-row>
  443. <el-col :span="12">
  444. <el-form-item label="退货电话">
  445. <el-input v-model="dialogForm.refundPhone" />
  446. </el-form-item>
  447. </el-col>
  448. <el-col :span="12">
  449. <el-form-item label="退货收货人">
  450. <el-input v-model="dialogForm.refundConsignee" />
  451. </el-form-item>
  452. </el-col>
  453. </el-row>
  454. <el-form-item label="寄件人电话">
  455. <el-input v-model="dialogForm.sendPhone" />
  456. </el-form-item>
  457. <el-row>
  458. <el-col :span="12">
  459. <el-form-item label="商品总数">
  460. <span>{{dialogForm.productCount || 0}}</span>
  461. </el-form-item>
  462. </el-col>
  463. <el-col :span="12">
  464. <el-form-item label="销量">
  465. <span>{{dialogForm.salesCount || 0}}</span>
  466. </el-form-item>
  467. </el-col>
  468. </el-row>
  469. <el-row>
  470. <el-col :span="12">
  471. <el-form-item label="累计金额">
  472. <span>{{dialogForm.totalMoney || 0}}</span>
  473. </el-form-item>
  474. </el-col>
  475. <el-col :span="12">
  476. <el-form-item label="分佣方式">
  477. <span v-if="dialogForm.brokerageType == 1">每盒</span>
  478. <span v-else-if="dialogForm.brokerageType == 2">总价</span>
  479. </el-form-item>
  480. </el-col>
  481. </el-row>
  482. <el-row>
  483. <el-col :span="12">
  484. <el-form-item label="状态">
  485. <dict-tag :options="statusOptions" :value="dialogForm.status"/>
  486. </el-form-item>
  487. </el-col>
  488. <el-col :span="12">
  489. <el-form-item label="审核状态">
  490. <dict-tag :options="isAuditOptions" :value="dialogForm.isAudit"/>
  491. </el-form-item>
  492. </el-col>
  493. </el-row>
  494. <el-form-item label="配送方式">
  495. <span v-if="dialogForm.shippingType">
  496. <span v-if="dialogForm.shippingType.includes('1') || dialogForm.shippingType === '1'">配送</span>
  497. <span v-if="dialogForm.shippingType.includes('2') || dialogForm.shippingType === '2'">,自提</span>
  498. <span v-if="dialogForm.shippingType.includes('3') || dialogForm.shippingType === '3'">,配送自提</span>
  499. </span>
  500. </el-form-item>
  501. <el-form-item label="登录帐号">
  502. <el-input v-model="dialogForm.account" />
  503. </el-form-item>
  504. </el-form>
  505. </template>
  506. </StoreDialog>
  507. <el-dialog :visible.sync="imagePreviewVisible" width="800px" append-to-body>
  508. <img :src="previewImageUrl" style="width: 100%; height: auto; max-height: 600px; object-fit: contain;" />
  509. </el-dialog>
  510. </div>
  511. </template>
  512. <script>
  513. import { audit, listStore, exportStore, getStore, getStoreAuditLog } from "@/api/hisStore/store";
  514. import { getCitys } from "@/api/store/city";
  515. import { getConfigByKey } from '@/api/system/config';
  516. import ImageUpload from '@/components/ImageUpload';
  517. import StoreDialog from '../components/StoreDialog.vue';
  518. export default {
  519. name: "adutstore",
  520. components: { ImageUpload, StoreDialog },
  521. data() {
  522. return {
  523. previewImageUrl: '',
  524. imagePreviewVisible: false,
  525. reportFileList:[],
  526. fileList:[],
  527. // 弹出层标题
  528. title: "",
  529. // 是否显示弹出层
  530. open: false,
  531. isAuditMode: false,
  532. // 审核表单
  533. auditForm: {
  534. reason: '',
  535. attachImage: ''
  536. },
  537. // 审核记录
  538. auditLogs: [],
  539. medicalMallConfig:{},
  540. citys:[],
  541. licenseuploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS",
  542. uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS",
  543. baseUrl: process.env.VUE_APP_BASE_API,
  544. shippingTypeOptions: [{
  545. "label": "配送",
  546. "value": "1"
  547. }, {
  548. "label": "自提",
  549. "value": "2"
  550. }, {
  551. "label": "配送自提",
  552. "value": "3"
  553. }],
  554. // 遮罩层
  555. loading: true,
  556. // 导出遮罩层
  557. exportLoading: false,
  558. // 选中数组
  559. ids: [],
  560. // 非单个禁用
  561. single: true,
  562. // 非多个禁用
  563. multiple: true,
  564. // 显示搜索条件
  565. showSearch: true,
  566. // 总条数
  567. total: 0,
  568. // 店铺管理表格数据
  569. storeList: [],
  570. // 状态字典
  571. statusOptions: [],
  572. // 审核状态字典
  573. isAuditOptions: [],
  574. // 查询参数
  575. queryParams: {
  576. pageNum: 1,
  577. pageSize: 10,
  578. storeName: null,
  579. address: null,
  580. phone: null,
  581. status: null,
  582. isAudit: 0,
  583. account: null,
  584. },
  585. // 表单参数
  586. form: {},
  587. // 表单校验
  588. rules: {
  589. storeName: [
  590. { required: true, message: "店铺名称不能为空", trigger: "blur" }
  591. ],
  592. logoUrl: [
  593. { required: true, message: "店铺LOGO不能为空", trigger: "blur" }
  594. ],
  595. cityIds: [
  596. { required: true, message: "所属城市不能为空", trigger: "blur" }
  597. ],
  598. address: [
  599. { required: true, message: "地址不能为空", trigger: "blur" }
  600. ],
  601. licenseImages: [
  602. { required: true, message: "资质证书不能为空", trigger: "blur" }
  603. ],
  604. shippingType: [
  605. { required: true, message: "配送方式不能为空", trigger: "blur" }
  606. ],
  607. phone: [
  608. { required: true, message: "店铺电话不能为空", trigger: "blur" }
  609. ],
  610. }
  611. };
  612. },
  613. created() {
  614. this.getCitys();
  615. this.getList();
  616. getConfigByKey("medicalMall.func.switch").then(response => {
  617. if(response.data && response.data.configValue) {
  618. this.medicalMallConfig = JSON.parse(response.data.configValue);
  619. }
  620. });
  621. this.getDicts("sys_company_status").then(response => {
  622. this.statusOptions = response.data;
  623. });
  624. this.getDicts("sys_company_isaudit").then(response => {
  625. this.isAuditOptions = response.data;
  626. });
  627. },
  628. methods: {
  629. /** 审核/详情按钮操作 */
  630. handledetails(row) {
  631. this.reset();
  632. this.isAuditMode = row.isAudit === 0; // 未审核的进入审核模式
  633. this.title = row.isAudit === 0 ? "店铺审核" : "店铺详情";
  634. const storeId = row.storeId;
  635. // 调用后端接口获取详情和审核记录
  636. Promise.all([getStore(storeId), getStoreAuditLog(storeId)])
  637. .then(([storeResponse, auditResponse]) => {
  638. this.form = storeResponse.data;
  639. // 处理食品经营许可证图片数据,支持逗号分隔的字符串
  640. if (this.form.foodLicense) {
  641. if (typeof this.form.foodLicense === 'string') {
  642. // 如果是逗号分隔的字符串,则分割成数组
  643. this.form.foodLicense = this.form.foodLicense.split(',').filter(url => url.trim() !== '');
  644. } else if (!Array.isArray(this.form.foodLicense)) {
  645. // 如果既不是字符串也不是数组,则初始化为空数组
  646. this.form.foodLicense = [];
  647. }
  648. } else {
  649. // 如果为空,则初始化为空数组
  650. this.form.foodLicense = [];
  651. }
  652. this.auditLogs = auditResponse.auditLog || [];
  653. this.reportFileList = this.urlToFileList(this.form.reportUrl);
  654. this.fileList = this.urlToFileList(this.form.filingUrl);
  655. this.open = true;
  656. })
  657. .catch(() => {
  658. this.msgError("获取店铺详情失败");
  659. });
  660. },
  661. /** 审核通过 */
  662. handleAuditPass() {
  663. this.$confirm('确认审核通过该店铺?', '提示', {
  664. confirmButtonText: '确定',
  665. cancelButtonText: '取消',
  666. type: 'warning'
  667. }).then(() => {
  668. const data = {
  669. storeId: this.form.storeId,
  670. isAudit: 1,
  671. reason: this.auditForm.reason,
  672. attachImage: this.auditForm.attachImage
  673. };
  674. return audit(data);
  675. }).then(res => {
  676. if (res.code === 200) {
  677. this.msgSuccess("审核通过成功");
  678. this.open = false;
  679. this.getList();
  680. // 清空审核表单
  681. this.auditForm = { reason: '', attachImage: '' };
  682. } else {
  683. this.msgError("审核失败");
  684. }
  685. }).catch(() => {});
  686. },
  687. /** 审核驳回 */
  688. handleAuditReject() {
  689. this.$confirm('确认驳回该店铺审核?', '提示', {
  690. confirmButtonText: '确定',
  691. cancelButtonText: '取消',
  692. type: 'warning'
  693. }).then(() => {
  694. const data = {
  695. storeId: this.form.storeId,
  696. isAudit: -1,
  697. reason: this.auditForm.reason,
  698. attachImage: this.auditForm.attachImage
  699. };
  700. return audit(data);
  701. }).then(res => {
  702. if (res.code === 200) {
  703. this.msgSuccess("审核驳回成功");
  704. this.open = false;
  705. this.getList();
  706. // 清空审核表单
  707. this.auditForm = { reason: '', attachImage: '' };
  708. } else {
  709. this.msgError("审核失败");
  710. }
  711. }).catch(() => {});
  712. },
  713. /** 处理审核提交 */
  714. handleAuditSubmit(auditData) {
  715. audit(auditData).then(res => {
  716. if (res.code === 200) {
  717. this.msgSuccess(auditData.isAudit === 1 ? "审核通过成功" : "审核驳回成功");
  718. this.open = false;
  719. this.getList();
  720. } else {
  721. this.msgError("审核失败");
  722. }
  723. }).catch(() => {
  724. this.msgError("审核操作失败");
  725. });
  726. },
  727. /** 对话框关闭 */
  728. handleDialogClose() {
  729. this.reset();
  730. },
  731. handleCityChange(value) {
  732. var nodes=this.$refs.citySelect.getCheckedNodes();
  733. this.form.address=nodes[0].pathLabels[0]+nodes[0].pathLabels[1]+nodes[0].pathLabels[2];
  734. this.form.cityIds=value.toString();
  735. },
  736. getCitys(){
  737. getCitys().then(res => {
  738. this.loading = false;
  739. this.citys=res.data;
  740. })
  741. },
  742. licensehandleAvatarSuccess(res, file) {
  743. if(res.code==200){
  744. this.form.licenseImages=res.url;
  745. this.$forceUpdate()
  746. }
  747. else{
  748. this.msgError(res.msg);
  749. }
  750. },
  751. handleAvatarSuccess(res, file) {
  752. if(res.code==200){
  753. this.form.logoUrl=res.url;
  754. this.$forceUpdate()
  755. }
  756. else{
  757. this.msgError(res.msg);
  758. }
  759. },
  760. beforeAvatarUpload(file) {
  761. const isLt1M = file.size / 1024 / 1024 < 1;
  762. if (!isLt1M) {
  763. this.$message.error('上传图片大小不能超过 1MB!');
  764. }
  765. return isLt1M;
  766. },
  767. handleClickX(){
  768. this.getList()
  769. },
  770. /** 查询店铺管理列表 */
  771. getList() {
  772. this.loading = true;
  773. listStore(this.queryParams).then(response => {
  774. this.storeList = response.rows;
  775. this.total = response.total;
  776. this.loading = false;
  777. });
  778. },
  779. // 取消按钮
  780. cancel() {
  781. this.open = false;
  782. this.reset();
  783. },
  784. // 表单重置
  785. reset() {
  786. this.form = {
  787. storeId: null,
  788. cityIds: null,
  789. storeName: null,
  790. descs: null,
  791. logoUrl: null,
  792. address: null,
  793. lng: null,
  794. lat: null,
  795. phone: null,
  796. licenseImages: null,
  797. productCount: null,
  798. status: 0,
  799. createTime: null,
  800. updateTime: null,
  801. salesCount: null,
  802. balance: null,
  803. totalMoney: null,
  804. isAudit: 0,
  805. account: null,
  806. password: null,
  807. shippingType: ["1"]
  808. };
  809. this.resetForm("form");
  810. },
  811. /** 搜索按钮操作 */
  812. handleQuery() {
  813. this.queryParams.pageNum = 1;
  814. this.getList();
  815. },
  816. /** 重置按钮操作 */
  817. resetQuery() {
  818. this.resetForm("queryForm");
  819. this.handleQuery();
  820. },
  821. // 多选框选中数据
  822. handleSelectionChange(selection) {
  823. this.ids = selection.map(item => item.storeId)
  824. this.single = selection.length!==1
  825. this.multiple = !selection.length
  826. },
  827. /** 导出按钮操作 */
  828. handleExport() {
  829. const queryParams = this.queryParams;
  830. this.$confirm('是否确认导出所有店铺管理数据项?', "警告", {
  831. confirmButtonText: "确定",
  832. cancelButtonText: "取消",
  833. type: "warning"
  834. }).then(() => {
  835. this.exportLoading = true;
  836. return exportStore(queryParams);
  837. }).then(response => {
  838. this.download(response.msg);
  839. this.exportLoading = false;
  840. }).catch(() => {});
  841. },
  842. handleRemove(file, fileList) {
  843. console.log(file, fileList);
  844. },
  845. handlePreview(file) {
  846. console.log(file);
  847. },
  848. handleExceed(files, fileList) {
  849. this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
  850. },
  851. beforeRemove(file, fileList) {
  852. return this.$confirm(`确定移除 ${ file.name }?`);
  853. },
  854. // 将逗号分隔的URL字符串转换为文件对象数组
  855. urlToFileList(urlStr) {
  856. if (!urlStr) return [];
  857. return urlStr.split(',').map(url => {
  858. const fileName = url.substring(url.lastIndexOf('/') + 1);
  859. return {
  860. name: fileName,
  861. url: url,
  862. uid: Date.now() + Math.random().toString(36).substr(2, 9) // 生成唯一ID
  863. };
  864. });
  865. },
  866. isImageFile(fileName) {
  867. const imageSuffix = ['jpg', 'jpeg', 'png', 'gif', 'bmp'];
  868. const suffix = fileName.split('.').pop().toLowerCase();
  869. return imageSuffix.includes(suffix);
  870. },
  871. handleFilePreview(file) {
  872. const { url, name } = file;
  873. if (this.isImageFile(name)) {
  874. this.previewImageUrl = url;
  875. this.imagePreviewVisible = true;
  876. } else {
  877. window.open(url, '_blank');
  878. }
  879. },
  880. // 添加图片预览方法
  881. previewImage(url) {
  882. this.previewImageUrl = url;
  883. this.imagePreviewVisible = true;
  884. },
  885. }
  886. };
  887. </script>
  888. <style>
  889. .avatar-uploader .el-upload {
  890. border: 1px dashed #d9d9d9;
  891. border-radius: 6px;
  892. cursor: pointer;
  893. position: relative;
  894. overflow: hidden;
  895. }
  896. .avatar-uploader .el-upload:hover {
  897. border-color: #409EFF;
  898. }
  899. .avatar-uploader-icon {
  900. font-size: 28px;
  901. color: #8c939d;
  902. width: 150px;
  903. height: 150px;
  904. line-height: 150px;
  905. text-align: center;
  906. }
  907. /* 无图片占位符样式 */
  908. .no-image-placeholder {
  909. width: 200px;
  910. height: 200px;
  911. border: 1px dashed #d9d9d9;
  912. border-radius: 6px;
  913. display: flex;
  914. align-items: center;
  915. justify-content: center;
  916. color: #999;
  917. background-color: #fafafa;
  918. }
  919. .upload-demo.el-upload--disabled {
  920. opacity: 0.6;
  921. cursor: not-allowed;
  922. pointer-events: none;
  923. }
  924. .upload-demo.el-upload--disabled .el-upload-list {
  925. display: block !important;
  926. }
  927. .avatar-uploader .el-upload {
  928. border: 1px dashed #d9d9d9;
  929. border-radius: 6px;
  930. cursor: pointer;
  931. position: relative;
  932. overflow: hidden;
  933. }
  934. /* 食品经营许可证容器 */
  935. .food-license-container {
  936. display: flex;
  937. flex-direction: row;
  938. flex-wrap: wrap;
  939. gap: 10px;
  940. align-items: flex-start;
  941. justify-content: flex-start;
  942. }
  943. /* 食品经营许可证单项 */
  944. .food-license-item {
  945. position: relative;
  946. display: inline-block;
  947. text-align: center;
  948. }
  949. .avatar {
  950. width: 200px;
  951. height: 200px;
  952. object-fit: cover;
  953. border-radius: 4px;
  954. }
  955. .small-avatar {
  956. width: 150px;
  957. height: 150px;
  958. }
  959. /* 无图片占位符样式 */
  960. .small-placeholder {
  961. width: 150px;
  962. height: 150px;
  963. }
  964. .avatar-wrapper {
  965. position: relative;
  966. display: inline-block;
  967. }
  968. /* 并排按钮样式 */
  969. .button-group {
  970. position: absolute;
  971. top: 10px;
  972. right: 10px;
  973. display: flex;
  974. gap: 5px;
  975. }
  976. .preview-btn {
  977. width: 30px;
  978. height: 30px;
  979. border-radius: 50%;
  980. background-color: rgba(0, 0, 0, 0.5);
  981. color: white;
  982. display: flex;
  983. align-items: center;
  984. justify-content: center;
  985. cursor: pointer;
  986. font-size: 16px;
  987. transition: background-color 0.3s;
  988. }
  989. .preview-btn:hover {
  990. background-color: rgba(0, 0, 0, 0.7);
  991. }
  992. </style>