AuditInfo.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <template>
  2. <view class="audit-info">
  3. <view class="font-bold mt-16" style="padding: 0 20rpx">
  4. 该书共{{ detail.num }}本,其中:良好{{ getAuditCateNum(1) }}本,一般{{ getAuditCateNum(2) }}本,极差{{
  5. getAuditCateNum(3)
  6. }}本
  7. </view>
  8. <view v-if="auditCommentList.length > 0" v-for="(audit, index) in auditCommentList" :key="index">
  9. <view class="mt-10 bind-code" style="padding: 10rpx 20rpx"> 第{{ index + 1 }}本的审核意见 </view>
  10. <view class="mt-20 bg-white flex flex-j-a flex-a-c" style="padding: 20rpx; border-radius: 10rpx">
  11. <view class="u-page__tag-item" v-for="(item, idx) in auditList" :key="idx">
  12. <u-tag
  13. size="large"
  14. :text="item.label"
  15. :plain="audit.sts != item.sts"
  16. type="primary"
  17. :name="item.sts"
  18. :class="{ disabled: item.sts == 2 }"
  19. @click="radioClick(audit, index, item.sts)"
  20. >
  21. </u-tag>
  22. </view>
  23. </view>
  24. <view class="mt-20 bg-white" style="padding: 20rpx; border-radius: 10rpx" v-if="audit.sts == 3">
  25. <view class="flex flex-a-c flex-wrap">
  26. <view
  27. class="mr-10 reason-item"
  28. v-for="(item, idx) in reasonList"
  29. :key="idx"
  30. @click="toggleReason(audit, index, item)"
  31. :class="{ selected: audit.comList.includes(item.label) }"
  32. >
  33. {{ item.label }}
  34. </view>
  35. </view>
  36. </view>
  37. </view>
  38. <!-- 悬浮排序按钮 -->
  39. <view class="floating-sort-btn" @click="sortByAuditStatus">
  40. <u-icon name="list" color="#FFFFFF" size="22"></u-icon>
  41. <text class="btn-text">排序</text>
  42. </view>
  43. </view>
  44. </template>
  45. <script setup>
  46. import { ref, watch, nextTick, onMounted } from "vue";
  47. const props = defineProps({
  48. detail: {
  49. type: Object,
  50. default: () => ({}),
  51. },
  52. auditList: {
  53. type: Array,
  54. default: () => [],
  55. },
  56. });
  57. const auditCommentList = ref([]);
  58. const initAuditList = (detail) => {
  59. if (!detail?.auditCommentList) return;
  60. auditCommentList.value = detail.auditCommentList.map((item, index) => ({
  61. ...item,
  62. idx: index,
  63. isbn: detail.isbn,
  64. comList: item.com ? (typeof item.com === "string" ? item.com.split(",") : item.com) : [],
  65. }));
  66. sortByAuditStatus();
  67. };
  68. watch(
  69. () => props.detail,
  70. () => {
  71. initAuditList(props.detail);
  72. },
  73. { deep: true, immediate: true }
  74. );
  75. const auditList = ref([
  76. { sts: 1, label: "品相良好" },
  77. { sts: 2, label: "品相一般", disabled: true },
  78. { sts: 3, label: "品相极差" },
  79. ]);
  80. const emit = defineEmits(["selected"]);
  81. const radioClick = (audit, index, sts) => {
  82. if (sts == 2) return;
  83. audit.sts = sts;
  84. if (sts == 1) {
  85. audit.comList = [];
  86. }
  87. auditCommentList.value[index] = audit;
  88. formatReason();
  89. };
  90. const getAuditCateNum = (cate) => {
  91. return props.detail.auditCommentList?.filter((item) => item.sts == cate)?.length || 0;
  92. };
  93. let reasonList = ref([
  94. { sts: 3, label: "明显泛黄水印/发霉/明显异味" },
  95. { sts: 3, label: "老化泛黄褪色/污渍" },
  96. { sts: 3, label: "明显破损/脱胶缺页/书籍变型" },
  97. { sts: 3, label: "无此书" },
  98. { sts: 3, label: "印刷不清晰" },
  99. { sts: 3, label: "无防伪" },
  100. { sts: 3, label: "无外护封/无ISBN" },
  101. { sts: 3, label: "无此书多其他书" },
  102. { sts: 3, label: "笔记杂乱/习题做完" },
  103. { sts: 3, label: "有笔记贴" },
  104. { sts: 3, label: "套装缺册" },
  105. { sts: 3, label: "听力无光盘" },
  106. { sts: 3, label: "图书馆/藏书印章" },
  107. ]);
  108. const formatReason = () => {
  109. let list = auditCommentList.value.map((item, index) => ({
  110. ...item,
  111. idx: index,
  112. com: item.comList.join(","),
  113. }));
  114. return list;
  115. };
  116. const toggleReason = (audit, index, item) => {
  117. const idx = audit.comList.indexOf(item.label);
  118. if (idx > -1) {
  119. audit.comList.splice(idx, 1);
  120. } else {
  121. audit.comList.push(item.label);
  122. }
  123. auditCommentList.value[index] = audit;
  124. };
  125. /**
  126. * 排序审核列表,未审核的放在前面,已审核的放在后面
  127. * @returns {Array} 排序后的审核列表
  128. */
  129. const sortByAuditStatus = () => {
  130. // 创建一个新数组避免直接修改原数组的顺序
  131. const sortedList = [...auditCommentList.value];
  132. // 排序:未审核状态(sts===0)的放前面,已审核的(sts===1或sts===3)放后面
  133. sortedList.sort((a, b) => {
  134. // 如果a是未审核(0),而b是已审核(1或3),则a排在前面
  135. if (a.sts === 0 && (b.sts === 1 || b.sts === 3)) {
  136. return -1;
  137. }
  138. // 如果b是未审核(0),而a是已审核(1或3),则b排在前面
  139. if (b.sts === 0 && (a.sts === 1 || a.sts === 3)) {
  140. return 1;
  141. }
  142. // 其他情况保持原顺序
  143. return 0;
  144. });
  145. // 更新引用,保持响应性
  146. auditCommentList.value = sortedList;
  147. return sortedList;
  148. };
  149. defineExpose({
  150. formatReason,
  151. initAuditList,
  152. sortByAuditStatus,
  153. });
  154. </script>
  155. <style lang="scss" scoped>
  156. .bind-code {
  157. background-color: #cecece;
  158. border-radius: 4rpx;
  159. }
  160. .reason-item {
  161. background-color: #f0f0f0;
  162. border-radius: 4rpx;
  163. padding: 14rpx 20rpx;
  164. margin-bottom: 16rpx;
  165. }
  166. .selected {
  167. background-color: #d0e8ff;
  168. }
  169. .disabled {
  170. background-color: #d0d0d0;
  171. }
  172. /* 悬浮排序按钮样式 */
  173. .floating-sort-btn {
  174. position: fixed;
  175. right: 20rpx;
  176. bottom: 30%;
  177. width: 90rpx;
  178. height: 90rpx;
  179. background: linear-gradient(135deg, #2b85e4, #5cadff);
  180. border-radius: 50%;
  181. display: flex;
  182. flex-direction: column;
  183. justify-content: center;
  184. align-items: center;
  185. z-index: 999;
  186. box-shadow: 0 4px 12px rgba(43, 133, 228, 0.3);
  187. }
  188. .btn-text {
  189. font-size: 24rpx;
  190. color: #FFFFFF;
  191. margin-top: 4rpx;
  192. }
  193. </style>