DataTableSlot.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <script lang="ts" setup>
  2. /**
  3. * @Name: DataTableSlot.vue
  4. * @Description: 商品监控-表格插槽
  5. * @Author: Cheney
  6. */
  7. import { useCountryInfoStore } from '/@/stores/countryInfo';
  8. import { CopyDocument, Delete, InfoFilled, Operation, Tickets, Timer } from '@element-plus/icons-vue';
  9. import { getTagType } from '/@/utils/useTagColor';
  10. import PermissionButton from '/@/components/PermissionButton/index.vue';
  11. import ProductInfo from '/@/views/product-manage/component/ProductInfo.vue';
  12. import ProgressBar from '/@/views/product-manage/product-monitor/component/ProgressBar.vue';
  13. import { handleCopy } from '/@/utils/useCopyText';
  14. const router = useRouter();
  15. const props = defineProps<{
  16. row: any,
  17. field: any
  18. }>();
  19. const { row, field } = props;
  20. const emit: any = defineEmits([ 'edit-row', 'handle-delete', 'show-history' ]);
  21. const countryInfoStore = useCountryInfoStore();
  22. const country = countryInfoStore.Countries.find(c => c.code == row.country_code);
  23. const color = country ? country.color : '#3875F6';
  24. const statusMap: { [key: number]: { text: string, type: string } } = {
  25. 1: { text: '正常', type: 'success' },
  26. 2: { text: '失败', type: 'danger' },
  27. 3: { text: '暂停', type: 'warning' },
  28. 10: { text: '下架', type: 'info' }
  29. };
  30. const { text: statusText, type: statusType } = statusMap[row.status] || { text: '未知', type: 'info' };
  31. function handleEdit() {
  32. emit('edit-row', row);
  33. }
  34. function onConfirm() {
  35. emit('handle-delete', row);
  36. }
  37. function showDetail(detail: any) {
  38. emit(`${ detail }`, row);
  39. }
  40. function goto() {
  41. const routeUrl = router.resolve({
  42. path: '/product/comment',
  43. query: {
  44. asin: row.asin,
  45. title: row.goods.title,
  46. img: row.goods.img,
  47. url: row.goods.url
  48. }
  49. });
  50. window.open(routeUrl.href, '_blank');
  51. }
  52. </script>
  53. <template>
  54. <div class="font-medium">
  55. <div v-if="field === 'product_info'">
  56. <ProductInfo :img-width="60" :item="row.goods" />
  57. </div>
  58. <div v-else-if="field === 'sku'" style="color: #1d2129;">
  59. <div v-if="row.goods.sku || row.goods.sku2 || row.goods.sku3" class="flex items-center justify-center max-h-5">
  60. <div v-if="row.goods.sku">
  61. {{ row.goods.sku }}
  62. <el-button :icon="CopyDocument" class="ml-1 cursor-pointer" link
  63. @click="handleCopy(row.goods.sku || '')"></el-button>
  64. </div>
  65. <div v-if="row.goods.sku2">
  66. {{ row.goods.sku2 }}
  67. <el-button :icon="CopyDocument" class="ml-1 cursor-pointer" link
  68. @click="handleCopy(row.goods.sku2 || '')"></el-button>
  69. </div>
  70. <div v-if="row.goods.sku3">
  71. {{ row.goods.sku3 }}
  72. <el-button :icon="CopyDocument" class="ml-1 cursor-pointer" link
  73. @click="handleCopy(row.goods.sku3 || '')"></el-button>
  74. </div>
  75. </div>
  76. <div v-else>
  77. -
  78. </div>
  79. </div>
  80. <div v-else-if="field === 'country_code'">
  81. <el-tag :disable-transitions="true" :style="{ color: color, borderColor: color }" effect="plain" round>
  82. {{ country ? country.name : '-' }}
  83. </el-tag>
  84. </div>
  85. <div v-else-if="field === 'shop_name'">
  86. <el-tag v-if="row.goods.shop_name" :disable-transitions="true" :type=getTagType(row.shop_name)>
  87. {{ row.shop_name }}
  88. </el-tag>
  89. <div v-else>-</div>
  90. </div>
  91. <div v-else-if="field === 'tag'">
  92. <el-tag v-if="row.goods.tag" :disable-transitions="true" :type=getTagType(row.goods.tag)>
  93. {{ row.goods.tag }}
  94. </el-tag>
  95. <div v-else>-</div>
  96. </div>
  97. <div v-else-if="field === 'brand'">
  98. <el-tag v-if="row.goods.brand" :disable-transitions="true" :type=getTagType(row.goods.brand) effect="plain" round>
  99. {{ row.goods.brand }}
  100. </el-tag>
  101. <div v-else>-</div>
  102. </div>
  103. <div v-else-if="field === 'price_info'">
  104. <div v-if="row.goods.price >= 0" class="font-medium">
  105. <p>现 价:{{ row.goods.currency_code + '‎' + row.goods.price }}</p>
  106. <p>折 扣:{{ row.goods.discount > 0 ? row.goods.discount + '%' : '-' }}</p>
  107. <p>优惠劵:{{ !row || row.goods.coupon <= 0 ? '-' : row.goods.currency_code + '‎' + row.goods.coupon }}</p>
  108. </div>
  109. </div>
  110. <div v-else-if="field === 'show_price'">
  111. <div class="font-medium">
  112. <p>展示价格:{{ row.goods.show_price ? row.goods.currency_code + row.goods.show_price : '-' }}</p>
  113. <p>平时售价:{{ row.goods.activity_price ? row.goods.currency_code + row.goods.activity_price : '-' }}</p>
  114. <p>最低售价:{{ row.goods.minimum_price ? row.goods.currency_code + row.goods.minimum_price : '-' }}</p>
  115. </div>
  116. </div>
  117. <div v-else-if="field === 'score'">
  118. <template v-if="row.goods.score !== null && row.goods.score !== undefined && row.goods.score !== ''">
  119. <el-rate
  120. v-if="row.goods.score > 0"
  121. v-model="row.goods.score"
  122. :colors="['#FF0000', '#FF9900', '#67C23A']"
  123. disabled
  124. show-score
  125. text-color="#1e293b"
  126. />
  127. <span v-else>{{ row.goods.score }}</span> <!-- 值为0时显示0 -->
  128. </template>
  129. <template v-else>
  130. <span>-</span> <!-- 无值时显示'--' -->
  131. </template>
  132. </div>
  133. <div v-else-if="field === 'all_score'">
  134. <template v-if="row.goods.all_score !== null && row.goods.all_score !== undefined && row.goods.all_score !== ''">
  135. <el-rate
  136. v-if="row.goods.all_score > 0"
  137. v-model="row.goods.all_score"
  138. :colors="['#FF0000', '#FF9900', '#67C23A']"
  139. disabled
  140. show-score
  141. text-color="#1e293b"
  142. />
  143. <span v-else>{{ row.goods.all_score }}</span>
  144. </template>
  145. <template v-else>
  146. <span>-</span>
  147. </template>
  148. </div>
  149. <div v-else-if="field === 'stars'" class="flex flex-col font-normal" style="min-width: 170px">
  150. <div v-for="i in [5,4,3,2,1]" :key="i" class="w-full flex items-center" style="max-height: 15px;">
  151. <span class="w-10 text-right mr-2 italic">{{ i }}星</span>
  152. <el-progress
  153. :color="'#3A8EE6'"
  154. :percentage="row.goods.ratings > 0 ? Math.round(row.goods[`ratings${i}`] / row.goods.ratings * 100) : 0"
  155. :stroke-width="10"
  156. class="flex-1"
  157. striped
  158. striped-flow
  159. />
  160. </div>
  161. </div>
  162. <div v-else-if="field === 'all_stars'" class="flex flex-col font-normal" style="min-width: 170px">
  163. <ProgressBar :row="row" percentage="all_rate" />
  164. </div>
  165. <div v-else-if="field === 'status'">
  166. <el-tag :disable-transitions="true" :type=statusType>
  167. {{ statusText }}
  168. </el-tag>
  169. </div>
  170. <div v-else-if="field === 'operate'">
  171. <div class="flex justify-center gap-2 mb-2">
  172. <div>
  173. <el-tooltip :enterable="false" :show-arrow="false" content="评论详情" hide-after="0"
  174. placement="top" popper-class="custom-btn-tooltip">
  175. <PermissionButton circle plain type="success" @click="goto">
  176. <el-icon>
  177. <Tickets />
  178. </el-icon>
  179. </PermissionButton>
  180. </el-tooltip>
  181. </div>
  182. <div>
  183. <el-tooltip :enterable="false" :show-arrow="false" content="历史详情" hide-after="0"
  184. placement="top" popper-class="custom-btn-tooltip-2">
  185. <PermissionButton :color="'#6466F1'" circle plain type="success" @click="showDetail('show-history')">
  186. <el-icon>
  187. <Timer />
  188. </el-icon>
  189. </PermissionButton>
  190. </el-tooltip>
  191. </div>
  192. </div>
  193. <div class="flex justify-center gap-2">
  194. <div>
  195. <PermissionButton circle plain type="warning" @click="handleEdit">
  196. <el-icon>
  197. <Operation />
  198. </el-icon>
  199. </PermissionButton>
  200. </div>
  201. <div>
  202. <el-popconfirm
  203. :icon="InfoFilled"
  204. icon-color="#626AEF"
  205. title="你确定要删除此项吗?"
  206. width="220"
  207. @confirm="onConfirm"
  208. >
  209. <template #reference>
  210. <PermissionButton circle plain type="danger">
  211. <el-icon>
  212. <Delete />
  213. </el-icon>
  214. </PermissionButton>
  215. </template>
  216. <template #actions="{ confirm, cancel }">
  217. <el-button size="small" @click="cancel">No!</el-button>
  218. <el-button
  219. size="small"
  220. type="danger"
  221. @click="confirm"
  222. >
  223. Yes?
  224. </el-button>
  225. </template>
  226. </el-popconfirm>
  227. </div>
  228. </div>
  229. </div>
  230. <div v-else>
  231. {{ row.goods[field] || '-' }}
  232. </div>
  233. </div>
  234. </template>
  235. <style scoped>
  236. :deep(.flex-1 .el-progress__text) {
  237. font-size: 14px !important;
  238. }
  239. </style>
  240. <style lang="scss">
  241. .custom-btn-tooltip {
  242. background-color: #EFF9EB !important;
  243. color: #606266 !important;
  244. border: 1px solid #67C23A !important;
  245. font-size: 14px;
  246. }
  247. .custom-btn-tooltip-2 {
  248. background-color: #F0F0FE !important;
  249. color: #606266 !important;
  250. border: 1px solid #6466F1 !important;
  251. font-size: 14px;
  252. }
  253. </style>