audit.vue 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174
  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. <img v-if="dialogForm.businessLicense" style="width: 200px; cursor: pointer" :src="dialogForm.businessLicense" @click="previewImage(dialogForm.businessLicense)" />
  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. <img v-if="dialogForm.drugLicense" style="width: 200px; cursor: pointer" :src="dialogForm.drugLicense" @click="previewImage(dialogForm.drugLicense)" />
  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. <img v-if="dialogForm.medicalDevice2" style="width: 200px; cursor: pointer" :src="dialogForm.medicalDevice2" @click="previewImage(dialogForm.medicalDevice2)" />
  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. <img v-if="dialogForm.medicalDevice3" style="width: 200px; cursor: pointer" :src="dialogForm.medicalDevice3" @click="previewImage(dialogForm.medicalDevice3)" />
  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" style="cursor: pointer" @click="previewImage(url)" />
  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. <div>
  406. <el-upload
  407. class="upload-demo"
  408. :action="uploadUrl"
  409. :on-preview="handleFilePreview"
  410. :on-remove="handleRemove"
  411. :before-remove="beforeRemove"
  412. :limit="1"
  413. :on-exceed="handleExceed"
  414. :file-list="reportFileList"
  415. :show-file-list="true"
  416. accept=".jpg,.jpeg,.png,.gif,.bmp,.pdf"
  417. disabled>
  418. <el-button size="small" type="primary" disabled>点击上传</el-button>
  419. <div slot="tip" class="el-upload__tip">支持 jpg/png/pdf 格式</div>
  420. </el-upload>
  421. <el-button
  422. v-if="dialogForm.reportUrl"
  423. type="text"
  424. size="small"
  425. icon="el-icon-view"
  426. style="margin-top: 4px;"
  427. @click="viewReportFile('reportUrl')">查看已上传文件</el-button>
  428. </div>
  429. </el-form-item>
  430. </el-col>
  431. <el-col :span="12">
  432. <el-form-item label="备案" prop="filingUrl">
  433. <div>
  434. <el-upload
  435. class="upload-demo"
  436. :action="uploadUrl"
  437. :on-preview="handleFilePreview"
  438. :on-remove="handleRemove"
  439. :before-remove="beforeRemove"
  440. :limit="1"
  441. :on-exceed="handleExceed"
  442. :file-list="fileList"
  443. :show-file-list="true"
  444. accept=".jpg,.jpeg,.png,.gif,.bmp,.pdf"
  445. disabled>
  446. <el-button size="small" type="primary" disabled>点击上传</el-button>
  447. <div slot="tip" class="el-upload__tip">支持 jpg/png/pdf 格式</div>
  448. </el-upload>
  449. <el-button
  450. v-if="dialogForm.filingUrl"
  451. type="text"
  452. size="small"
  453. icon="el-icon-view"
  454. style="margin-top: 4px;"
  455. @click="viewReportFile('filingUrl')">查看已上传文件</el-button>
  456. </div>
  457. </el-form-item>
  458. </el-col>
  459. <el-form-item label="退货地址">
  460. <el-input v-model="dialogForm.refundAddress" />
  461. </el-form-item>
  462. <el-row>
  463. <el-col :span="12">
  464. <el-form-item label="退货电话">
  465. <el-input v-model="dialogForm.refundPhone" />
  466. </el-form-item>
  467. </el-col>
  468. <el-col :span="12">
  469. <el-form-item label="退货收货人">
  470. <el-input v-model="dialogForm.refundConsignee" />
  471. </el-form-item>
  472. </el-col>
  473. </el-row>
  474. <el-form-item label="寄件人电话">
  475. <el-input v-model="dialogForm.sendPhone" />
  476. </el-form-item>
  477. <el-row>
  478. <el-col :span="12">
  479. <el-form-item label="商品总数">
  480. <span>{{dialogForm.productCount || 0}}</span>
  481. </el-form-item>
  482. </el-col>
  483. <el-col :span="12">
  484. <el-form-item label="销量">
  485. <span>{{dialogForm.salesCount || 0}}</span>
  486. </el-form-item>
  487. </el-col>
  488. </el-row>
  489. <el-row>
  490. <el-col :span="12">
  491. <el-form-item label="累计金额">
  492. <span>{{dialogForm.totalMoney || 0}}</span>
  493. </el-form-item>
  494. </el-col>
  495. <el-col :span="12" v-if="false">
  496. <el-form-item label="分佣方式">
  497. <span v-if="dialogForm.brokerageType == 1">每盒</span>
  498. <span v-else-if="dialogForm.brokerageType == 2">总价</span>
  499. </el-form-item>
  500. </el-col>
  501. </el-row>
  502. <el-row>
  503. <el-col :span="12" v-if="false">
  504. <el-form-item label="状态">
  505. <dict-tag :options="statusOptions" :value="dialogForm.status"/>
  506. </el-form-item>
  507. </el-col>
  508. <el-col :span="12">
  509. <el-form-item label="审核状态">
  510. <dict-tag :options="isAuditOptions" :value="dialogForm.isAudit"/>
  511. </el-form-item>
  512. </el-col>
  513. </el-row>
  514. <el-form-item label="配送方式" v-if="false">
  515. <span v-if="dialogForm.shippingType">
  516. <span v-if="dialogForm.shippingType.includes('1') || dialogForm.shippingType === '1'">配送</span>
  517. <span v-if="dialogForm.shippingType.includes('2') || dialogForm.shippingType === '2'">,自提</span>
  518. <span v-if="dialogForm.shippingType.includes('3') || dialogForm.shippingType === '3'">,配送自提</span>
  519. </span>
  520. </el-form-item>
  521. <el-form-item label="登录帐号">
  522. <el-input v-model="dialogForm.account" />
  523. </el-form-item>
  524. </el-form>
  525. </template>
  526. </StoreDialog>
  527. <el-dialog :visible.sync="imagePreviewVisible" width="1100px" append-to-body :modal-append-to-body="false" @close="onImagePreviewClose">
  528. <div slot="title">
  529. <span>图片预览</span>
  530. <span style="margin-left: 16px; font-size: 13px; color: #909399;">{{ previewScale }}%</span>
  531. </div>
  532. <div
  533. class="img-preview-body"
  534. @wheel.prevent="onPreviewWheel"
  535. @mousedown="onImgMouseDown"
  536. @mousemove="onImgMouseMove"
  537. @mouseup="onImgMouseUp"
  538. @mouseleave="onImgMouseUp"
  539. >
  540. <img
  541. :src="previewImageUrl"
  542. :style="{
  543. transform: `translate(${dragOffset.x}px, ${dragOffset.y}px) scale(${previewScale / 100})`,
  544. transition: isDragging ? 'none' : 'transform .15s',
  545. cursor: isDragging ? 'grabbing' : (previewScale > 100 ? 'grab' : 'default')
  546. }"
  547. style="max-width: 100%; max-height: 65vh; user-select: none;"
  548. ref="previewImg"
  549. @dragstart.prevent
  550. />
  551. </div>
  552. <div slot="footer" class="dialog-footer" style="text-align: left;">
  553. <el-button-group>
  554. <el-button size="small" icon="el-icon-zoom-out" :disabled="previewScale <= 25" @click="zoomOut">缩小</el-button>
  555. <el-button size="small" icon="el-icon-refresh" @click="resetZoom">复位</el-button>
  556. <el-button size="small" icon="el-icon-zoom-in" :disabled="previewScale >= 300" @click="zoomIn">放大</el-button>
  557. </el-button-group>
  558. <el-button size="small" style="float: right;" @click="imagePreviewVisible = false">关 闭</el-button>
  559. </div>
  560. </el-dialog>
  561. </div>
  562. </template>
  563. <script>
  564. import { audit, listStore, exportStore, getStore, getStoreAuditLog } from "@/api/hisStore/store";
  565. import { getCitys } from "@/api/store/city";
  566. import { getConfigByKey } from '@/api/system/config';
  567. import ImageUpload from '@/components/ImageUpload';
  568. import StoreDialog from '../components/StoreDialog.vue';
  569. export default {
  570. name: "adutstore",
  571. components: { ImageUpload, StoreDialog },
  572. data() {
  573. return {
  574. previewImageUrl: '',
  575. imagePreviewVisible: false,
  576. previewScale: 100,
  577. dragOffset: { x: 0, y: 0 },
  578. isDragging: false,
  579. dragStart: { x: 0, y: 0 },
  580. reportFileList:[],
  581. fileList:[],
  582. // 弹出层标题
  583. title: "",
  584. // 是否显示弹出层
  585. open: false,
  586. isAuditMode: false,
  587. // 审核表单
  588. auditForm: {
  589. reason: '',
  590. attachImage: ''
  591. },
  592. // 审核记录
  593. auditLogs: [],
  594. medicalMallConfig:{},
  595. citys:[],
  596. licenseuploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS",
  597. uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS",
  598. baseUrl: process.env.VUE_APP_BASE_API,
  599. shippingTypeOptions: [{
  600. "label": "配送",
  601. "value": "1"
  602. }, {
  603. "label": "自提",
  604. "value": "2"
  605. }, {
  606. "label": "配送自提",
  607. "value": "3"
  608. }],
  609. // 遮罩层
  610. loading: true,
  611. // 导出遮罩层
  612. exportLoading: false,
  613. // 选中数组
  614. ids: [],
  615. // 非单个禁用
  616. single: true,
  617. // 非多个禁用
  618. multiple: true,
  619. // 显示搜索条件
  620. showSearch: true,
  621. // 总条数
  622. total: 0,
  623. // 店铺管理表格数据
  624. storeList: [],
  625. // 状态字典
  626. statusOptions: [],
  627. // 审核状态字典
  628. isAuditOptions: [],
  629. // 查询参数
  630. queryParams: {
  631. pageNum: 1,
  632. pageSize: 10,
  633. storeName: null,
  634. address: null,
  635. phone: null,
  636. status: null,
  637. isAudit: 0,
  638. account: null,
  639. },
  640. // 表单参数
  641. form: {},
  642. // 表单校验
  643. rules: {
  644. storeName: [
  645. { required: true, message: "店铺名称不能为空", trigger: "blur" }
  646. ],
  647. logoUrl: [
  648. { required: true, message: "店铺LOGO不能为空", trigger: "blur" }
  649. ],
  650. cityIds: [
  651. { required: true, message: "所属城市不能为空", trigger: "blur" }
  652. ],
  653. address: [
  654. { required: true, message: "地址不能为空", trigger: "blur" }
  655. ],
  656. licenseImages: [
  657. { required: true, message: "资质证书不能为空", trigger: "blur" }
  658. ],
  659. phone: [
  660. { required: true, message: "店铺电话不能为空", trigger: "blur" }
  661. ],
  662. }
  663. };
  664. },
  665. created() {
  666. this.getCitys();
  667. this.getList();
  668. getConfigByKey("medicalMall.func.switch").then(response => {
  669. if(response.data && response.data.configValue) {
  670. this.medicalMallConfig = JSON.parse(response.data.configValue);
  671. }
  672. });
  673. this.getDicts("sys_company_status").then(response => {
  674. this.statusOptions = response.data;
  675. });
  676. this.getDicts("sys_company_isaudit").then(response => {
  677. this.isAuditOptions = response.data;
  678. });
  679. },
  680. methods: {
  681. /** 审核/详情按钮操作 */
  682. handledetails(row) {
  683. this.reset();
  684. this.isAuditMode = row.isAudit === 0; // 未审核的进入审核模式
  685. this.title = row.isAudit === 0 ? "店铺审核" : "店铺详情";
  686. const storeId = row.storeId;
  687. // 调用后端接口获取详情和审核记录
  688. Promise.all([getStore(storeId), getStoreAuditLog(storeId)])
  689. .then(([storeResponse, auditResponse]) => {
  690. this.form = storeResponse.data;
  691. // 处理食品经营许可证图片数据,支持逗号分隔的字符串
  692. if (this.form.foodLicense) {
  693. if (typeof this.form.foodLicense === 'string') {
  694. // 如果是逗号分隔的字符串,则分割成数组
  695. this.form.foodLicense = this.form.foodLicense.split(',').filter(url => url.trim() !== '');
  696. } else if (!Array.isArray(this.form.foodLicense)) {
  697. // 如果既不是字符串也不是数组,则初始化为空数组
  698. this.form.foodLicense = [];
  699. }
  700. } else {
  701. // 如果为空,则初始化为空数组
  702. this.form.foodLicense = [];
  703. }
  704. this.auditLogs = auditResponse.auditLog || [];
  705. this.reportFileList = this.urlToFileList(this.form.reportUrl);
  706. this.fileList = this.urlToFileList(this.form.filingUrl);
  707. this.open = true;
  708. })
  709. .catch(() => {
  710. this.msgError("获取店铺详情失败");
  711. });
  712. },
  713. /** 审核通过 */
  714. handleAuditPass() {
  715. this.$confirm('确认审核通过该店铺?', '提示', {
  716. confirmButtonText: '确定',
  717. cancelButtonText: '取消',
  718. type: 'warning'
  719. }).then(() => {
  720. const data = {
  721. storeId: this.form.storeId,
  722. isAudit: 1,
  723. reason: this.auditForm.reason,
  724. attachImage: this.auditForm.attachImage
  725. };
  726. return audit(data);
  727. }).then(res => {
  728. if (res.code === 200) {
  729. this.msgSuccess("审核通过成功");
  730. this.open = false;
  731. this.getList();
  732. // 清空审核表单
  733. this.auditForm = { reason: '', attachImage: '' };
  734. } else {
  735. this.msgError("审核失败");
  736. }
  737. }).catch(() => {});
  738. },
  739. /** 审核驳回 */
  740. handleAuditReject() {
  741. this.$confirm('确认驳回该店铺审核?', '提示', {
  742. confirmButtonText: '确定',
  743. cancelButtonText: '取消',
  744. type: 'warning'
  745. }).then(() => {
  746. const data = {
  747. storeId: this.form.storeId,
  748. isAudit: -1,
  749. reason: this.auditForm.reason,
  750. attachImage: this.auditForm.attachImage
  751. };
  752. return audit(data);
  753. }).then(res => {
  754. if (res.code === 200) {
  755. this.msgSuccess("审核驳回成功");
  756. this.open = false;
  757. this.getList();
  758. // 清空审核表单
  759. this.auditForm = { reason: '', attachImage: '' };
  760. } else {
  761. this.msgError("审核失败");
  762. }
  763. }).catch(() => {});
  764. },
  765. /** 处理审核提交 */
  766. handleAuditSubmit(auditData) {
  767. audit(auditData).then(res => {
  768. if (res.code === 200) {
  769. this.msgSuccess(auditData.isAudit === 1 ? "审核通过成功" : "审核驳回成功");
  770. this.open = false;
  771. this.getList();
  772. } else {
  773. this.msgError("审核失败");
  774. }
  775. }).catch(() => {
  776. this.msgError("审核操作失败");
  777. });
  778. },
  779. /** 对话框关闭 */
  780. handleDialogClose() {
  781. this.reset();
  782. },
  783. handleCityChange(value) {
  784. var nodes=this.$refs.citySelect.getCheckedNodes();
  785. this.form.address=nodes[0].pathLabels[0]+nodes[0].pathLabels[1]+nodes[0].pathLabels[2];
  786. this.form.cityIds=value.toString();
  787. },
  788. getCitys(){
  789. getCitys().then(res => {
  790. this.loading = false;
  791. this.citys=res.data;
  792. })
  793. },
  794. licensehandleAvatarSuccess(res, file) {
  795. if(res.code==200){
  796. this.form.licenseImages=res.url;
  797. this.$forceUpdate()
  798. }
  799. else{
  800. this.msgError(res.msg);
  801. }
  802. },
  803. handleAvatarSuccess(res, file) {
  804. if(res.code==200){
  805. this.form.logoUrl=res.url;
  806. this.$forceUpdate()
  807. }
  808. else{
  809. this.msgError(res.msg);
  810. }
  811. },
  812. beforeAvatarUpload(file) {
  813. const isLt1M = file.size / 1024 / 1024 < 1;
  814. if (!isLt1M) {
  815. this.$message.error('上传图片大小不能超过 1MB!');
  816. }
  817. return isLt1M;
  818. },
  819. handleClickX(){
  820. this.getList()
  821. },
  822. /** 查询店铺管理列表 */
  823. getList() {
  824. this.loading = true;
  825. listStore(this.queryParams).then(response => {
  826. this.storeList = response.rows;
  827. this.total = response.total;
  828. this.loading = false;
  829. });
  830. },
  831. // 取消按钮
  832. cancel() {
  833. this.open = false;
  834. this.reset();
  835. },
  836. // 表单重置
  837. reset() {
  838. this.reportFileList = [];
  839. this.fileList = [];
  840. this.form = {
  841. storeId: null,
  842. cityIds: null,
  843. storeName: null,
  844. descs: null,
  845. logoUrl: null,
  846. address: null,
  847. lng: null,
  848. lat: null,
  849. phone: null,
  850. licenseImages: null,
  851. productCount: null,
  852. status: 0,
  853. createTime: null,
  854. updateTime: null,
  855. salesCount: null,
  856. balance: null,
  857. totalMoney: null,
  858. isAudit: 0,
  859. account: null,
  860. password: null,
  861. shippingType: ["1"]
  862. };
  863. this.resetForm("form");
  864. },
  865. /** 搜索按钮操作 */
  866. handleQuery() {
  867. this.queryParams.pageNum = 1;
  868. this.getList();
  869. },
  870. /** 重置按钮操作 */
  871. resetQuery() {
  872. this.resetForm("queryForm");
  873. this.handleQuery();
  874. },
  875. // 多选框选中数据
  876. handleSelectionChange(selection) {
  877. this.ids = selection.map(item => item.storeId)
  878. this.single = selection.length!==1
  879. this.multiple = !selection.length
  880. },
  881. /** 导出按钮操作 */
  882. handleExport() {
  883. const queryParams = this.queryParams;
  884. this.$confirm('是否确认导出所有店铺管理数据项?', "警告", {
  885. confirmButtonText: "确定",
  886. cancelButtonText: "取消",
  887. type: "warning"
  888. }).then(() => {
  889. this.exportLoading = true;
  890. return exportStore(queryParams);
  891. }).then(response => {
  892. this.download(response.msg);
  893. this.exportLoading = false;
  894. }).catch(() => {});
  895. },
  896. handleRemove(file, fileList) {
  897. console.log(file, fileList);
  898. },
  899. handlePreview(file) {
  900. console.log(file);
  901. },
  902. handleExceed(files, fileList) {
  903. this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
  904. },
  905. beforeRemove(file, fileList) {
  906. return this.$confirm(`确定移除 ${ file.name }?`);
  907. },
  908. // 将逗号分隔的URL字符串转换为文件对象数组
  909. urlToFileList(urlStr) {
  910. if (!urlStr) return [];
  911. return urlStr.split(',').map(url => {
  912. const fileName = url.substring(url.lastIndexOf('/') + 1);
  913. return {
  914. name: fileName,
  915. url: url,
  916. uid: Date.now() + Math.random().toString(36).substr(2, 9) // 生成唯一ID
  917. };
  918. });
  919. },
  920. isImageFile(fileName) {
  921. const imageSuffix = ['jpg', 'jpeg', 'png', 'gif', 'bmp'];
  922. const suffix = fileName.split('.').pop().toLowerCase();
  923. return imageSuffix.includes(suffix);
  924. },
  925. handleFilePreview(file) {
  926. const { url, name } = file;
  927. if (this.isImageFile(name)) {
  928. this.previewImageUrl = url;
  929. this.previewScale = 100;
  930. this.imagePreviewVisible = true;
  931. } else {
  932. window.open(url, '_blank');
  933. }
  934. },
  935. viewReportFile(field) {
  936. const url = this.form[field]
  937. if (!url) {
  938. this.$message.warning('暂无文件')
  939. return
  940. }
  941. if (this.isImageFile(url.split('?')[0])) {
  942. this.previewImageUrl = url
  943. this.previewScale = 100
  944. this.imagePreviewVisible = true
  945. } else {
  946. window.open(url, '_blank')
  947. }
  948. },
  949. onImagePreviewClose() {
  950. this.previewScale = 100
  951. this.dragOffset = { x: 0, y: 0 }
  952. this.isDragging = false
  953. this.imagePreviewVisible = false
  954. },
  955. zoomOut() {
  956. if (this.previewScale > 25) {
  957. this.previewScale = Math.max(25, this.previewScale - 25)
  958. this.dragOffset = { x: 0, y: 0 }
  959. }
  960. },
  961. zoomIn() {
  962. if (this.previewScale < 300) {
  963. this.previewScale = Math.min(300, this.previewScale + 25)
  964. }
  965. },
  966. resetZoom() {
  967. this.previewScale = 100
  968. this.dragOffset = { x: 0, y: 0 }
  969. },
  970. onPreviewWheel(e) {
  971. if (e.deltaY < 0) {
  972. this.zoomIn()
  973. } else {
  974. this.zoomOut()
  975. }
  976. },
  977. onImgMouseDown(e) {
  978. this.isDragging = true
  979. this.dragStart = { x: e.clientX - this.dragOffset.x, y: e.clientY - this.dragOffset.y }
  980. },
  981. onImgMouseMove(e) {
  982. if (!this.isDragging) return
  983. this.dragOffset = {
  984. x: e.clientX - this.dragStart.x,
  985. y: e.clientY - this.dragStart.y
  986. }
  987. },
  988. onImgMouseUp() {
  989. this.isDragging = false
  990. },
  991. // 添加图片预览方法
  992. previewImage(url) {
  993. this.previewImageUrl = url;
  994. this.previewScale = 100;
  995. this.imagePreviewVisible = true;
  996. },
  997. }
  998. };
  999. </script>
  1000. <style>
  1001. .avatar-uploader .el-upload {
  1002. border: 1px dashed #d9d9d9;
  1003. border-radius: 6px;
  1004. cursor: pointer;
  1005. position: relative;
  1006. overflow: hidden;
  1007. }
  1008. .avatar-uploader .el-upload:hover {
  1009. border-color: #409EFF;
  1010. }
  1011. .avatar-uploader-icon {
  1012. font-size: 28px;
  1013. color: #8c939d;
  1014. width: 150px;
  1015. height: 150px;
  1016. line-height: 150px;
  1017. text-align: center;
  1018. }
  1019. /* 无图片占位符样式 */
  1020. .no-image-placeholder {
  1021. width: 200px;
  1022. height: 200px;
  1023. border: 1px dashed #d9d9d9;
  1024. border-radius: 6px;
  1025. display: flex;
  1026. align-items: center;
  1027. justify-content: center;
  1028. color: #999;
  1029. background-color: #fafafa;
  1030. }
  1031. .upload-demo.el-upload--disabled {
  1032. opacity: 0.6;
  1033. cursor: not-allowed;
  1034. pointer-events: none;
  1035. }
  1036. .upload-demo.el-upload--disabled .el-upload-list {
  1037. display: block !important;
  1038. }
  1039. .avatar-uploader .el-upload {
  1040. border: 1px dashed #d9d9d9;
  1041. border-radius: 6px;
  1042. cursor: pointer;
  1043. position: relative;
  1044. overflow: hidden;
  1045. }
  1046. /* 食品经营许可证容器 */
  1047. .food-license-container {
  1048. display: flex;
  1049. flex-direction: row;
  1050. flex-wrap: wrap;
  1051. gap: 10px;
  1052. align-items: flex-start;
  1053. justify-content: flex-start;
  1054. }
  1055. /* 食品经营许可证单项 */
  1056. .food-license-item {
  1057. position: relative;
  1058. display: inline-block;
  1059. text-align: center;
  1060. }
  1061. .avatar {
  1062. width: 200px;
  1063. height: 200px;
  1064. object-fit: cover;
  1065. border-radius: 4px;
  1066. }
  1067. .small-avatar {
  1068. width: 150px;
  1069. height: 150px;
  1070. }
  1071. /* 无图片占位符样式 */
  1072. .small-placeholder {
  1073. width: 150px;
  1074. height: 150px;
  1075. }
  1076. .avatar-wrapper {
  1077. position: relative;
  1078. display: inline-block;
  1079. }
  1080. /* 并排按钮样式 */
  1081. .button-group {
  1082. position: absolute;
  1083. top: 10px;
  1084. right: 10px;
  1085. display: flex;
  1086. gap: 5px;
  1087. }
  1088. .preview-btn {
  1089. width: 30px;
  1090. height: 30px;
  1091. border-radius: 50%;
  1092. background-color: rgba(0, 0, 0, 0.5);
  1093. color: white;
  1094. display: flex;
  1095. align-items: center;
  1096. justify-content: center;
  1097. cursor: pointer;
  1098. font-size: 16px;
  1099. transition: background-color 0.3s;
  1100. }
  1101. .preview-btn:hover {
  1102. background-color: rgba(0, 0, 0, 0.7);
  1103. }
  1104. .img-preview-body {
  1105. display: flex;
  1106. align-items: center;
  1107. justify-content: center;
  1108. min-height: 300px;
  1109. overflow: hidden;
  1110. }
  1111. </style>