四零语境前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

332 lines
8.1 KiB

2 days ago
  1. <template>
  2. <view class="home-container">
  3. <!-- 顶部横幅图片 -->
  4. <view class="banner-section">
  5. <!-- <image class="banner-image" src="@/static/首页背景图.png" mode="aspectFill"></image> -->
  6. <uv-swiper :list="bannerList" :loading="!bannerList.length" height="250"></uv-swiper>
  7. </view>
  8. <!-- 搜索区域 -->
  9. <SearchInput
  10. v-model="searchValue"
  11. placeholder="请输入展品名称"
  12. search-button-text="搜索"
  13. @search="handleSearch"
  14. />
  15. <!-- 展品分类 -->
  16. <view class="category-section" @click="openPicker">
  17. <view class="category-label">{{ selectedCategory.label ||'展品分类' }}</view>
  18. <uv-icon name="arrow-down-fill" size="14" color="#C70019"></uv-icon>
  19. <uv-picker ref="picker" confirmColor="#C70019" :columns="[columns[0], columns[1][0]]" keyName="label" @confirm="onCategoryConfirm" @change="onCategoryChange"></uv-picker>
  20. </view>
  21. <!-- 展品列表 -->
  22. <view class="exhibit-list">
  23. <view class="exhibit-item" v-for="(item, index) in list" :key="index" @click="handleItemClick(item)">
  24. <view class="item-header">
  25. <text class="item-id">{{ item.id }}</text>
  26. <img src="@/static/copy.png" alt="我是复制黏贴" class="item-icon" @click="copyId(item.id)">
  27. </view>
  28. <view class="item-border" />
  29. <view class="item-content">
  30. <view class="content-row">
  31. <text class="name">{{ item.title }}</text>
  32. </view>
  33. <view class="content-row">
  34. <text class="label">展品编号</text>
  35. <text class="value">{{ item.id }}</text>
  36. </view>
  37. <view class="content-row">
  38. <text class="label">展品位置</text>
  39. <text class="value">{{ item.position }}</text>
  40. </view>
  41. <view class="content-row">
  42. <text class="label">展品类型</text>
  43. <text class="value">{{ item.categoryId_dictText }}</text>
  44. </view>
  45. <view class="content-row">
  46. <text class="label">下次保养日期</text>
  47. <text class="value">{{ item.maintenanceDate }}</text>
  48. <view v-if="item.maintenanceProject" class="project">
  49. {{ item.maintenanceProject }}
  50. </view>
  51. </view>
  52. </view>
  53. <view class="item-actions">
  54. <uv-button
  55. size="small"
  56. color="#c70019"
  57. shape="circle"
  58. text="申请报修"
  59. @click.stop="handleRepair(item)"
  60. ></uv-button>
  61. <uv-button
  62. size="small"
  63. text="保养提交"
  64. color="#c70019"
  65. shape="circle"
  66. plain
  67. @click.stop="handleMaintenance(item)"
  68. ></uv-button>
  69. <uv-button
  70. color="#c70019"
  71. shape="circle"
  72. size="small"
  73. text="维修/保养记录"
  74. plain
  75. @click.stop="handleRecord(item)"
  76. ></uv-button>
  77. </view>
  78. </view>
  79. </view>
  80. <!-- 空状态 -->
  81. <uv-empty v-if="!list.length" icon="/static/暂无搜索结果.png" />
  82. </view>
  83. </template>
  84. <script>
  85. import SearchInput from '@/pages/components/SearchInput.vue'
  86. import ListMixin from '@/mixins/list'
  87. export default {
  88. mixins: [ListMixin],
  89. components: {
  90. SearchInput
  91. },
  92. data() {
  93. return {
  94. mixinListApi: 'exhibit.queryShowpieceList',
  95. searchValue: '',
  96. selectedCategory: {
  97. label: '',
  98. value: ''
  99. },
  100. // 轮播图数据
  101. bannerList: [],
  102. }
  103. },
  104. computed: {
  105. // 从状态管理工具中拿分类大数组
  106. columns() {
  107. return this.$store.state.categoryList
  108. }
  109. },
  110. methods: {
  111. handleSearch() {
  112. console.log('搜索的数值为', this.searchValue);
  113. this.initPage()
  114. this.getList(true)
  115. },
  116. mixinSetParams() {
  117. const params = { }
  118. if (this.selectedCategory.value) {
  119. params.categoryId = this.selectedCategory.value
  120. }
  121. return {
  122. title: this.searchValue,
  123. ...params
  124. }
  125. },
  126. openPicker() {
  127. this.$refs.picker.open()
  128. },
  129. onCategoryConfirm(e) {
  130. this.selectedCategory = e.value[1]
  131. console.log('选择分类:', e)
  132. this.initPage()
  133. this.getList(true)
  134. // TODO: 根据分类筛选展品
  135. },
  136. onCategoryChange(e) {
  137. const { columnIndex , index} = e
  138. if (columnIndex === 0) {
  139. this.$refs.picker.setColumnValues(1, this.columns[1][index])
  140. }
  141. },
  142. copyId(id) {
  143. uni.setClipboardData({
  144. data: id,
  145. success: () => {
  146. uni.showToast({
  147. title: '已复制到剪贴板',
  148. icon: 'success'
  149. })
  150. }
  151. })
  152. },
  153. handleItemClick(item) {
  154. console.log('点击展品:', item)
  155. // TODO: 跳转到展品详情页
  156. },
  157. handleRepair(item) {
  158. uni.navigateTo({
  159. url: '/subPages/home/repairSubmit?id=' + item.id
  160. })
  161. // TODO: 跳转到报修页面
  162. },
  163. handleMaintenance(item) {
  164. console.log('保养提交:', item)
  165. uni.navigateTo({
  166. url: '/subPages/home/maintainanceSubmit?id=' + item.id
  167. })
  168. // TODO: 跳转到保养提交页面
  169. },
  170. handleRecord(item) {
  171. console.log('查看记录:', item)
  172. uni.navigateTo({
  173. url: '/subPages/home/RAArecord?id=' + item.id
  174. })
  175. },
  176. async getBannerList() {
  177. const bannerRes = await this.$api.config.queryBannerList()
  178. if (bannerRes.code === 200) {
  179. this.bannerList = bannerRes.result.records.map(item => item.image)
  180. }
  181. },
  182. },
  183. onLoad(){
  184. this.getBannerList()
  185. },
  186. }
  187. </script>
  188. <style lang="scss" scoped>
  189. .home-container {
  190. background-color: #fff;
  191. min-height: 100vh;
  192. }
  193. .banner-section {
  194. width: 100%;
  195. height: 500rpx;
  196. .banner-image {
  197. width: 100%;
  198. height: 100%;
  199. }
  200. }
  201. .category-section {
  202. padding: 20rpx 48rpx;
  203. display: flex;
  204. align-items: center;
  205. justify-content: start;
  206. gap: 9rpx;
  207. .category-label {
  208. font-size: 28rpx;
  209. color: $primary-color;
  210. }
  211. .category-picker {
  212. display: flex;
  213. align-items: center;
  214. padding: 10rpx 20rpx;
  215. border: 1rpx solid #ddd;
  216. border-radius: 8rpx;
  217. background-color: #fafafa;
  218. .category-text {
  219. font-size: 28rpx;
  220. color: #666;
  221. margin-right: 10rpx;
  222. }
  223. }
  224. }
  225. .exhibit-list {
  226. padding: 20rpx 30rpx;
  227. .exhibit-item {
  228. background-color: #fff;
  229. border-radius: 16rpx;
  230. padding: 30rpx 30rpx 45rpx;
  231. margin-bottom: 20rpx;
  232. border-radius: 15rpx;
  233. box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
  234. .item-header {
  235. display: flex;
  236. align-items: center;
  237. justify-content: start;
  238. gap: 20rpx;
  239. padding-bottom: 14rpx;
  240. .item-id {
  241. font-size: 28rpx;
  242. color: $secondary-text-color;
  243. }
  244. .item-icon {
  245. width: 25.5rpx;
  246. height: 25.5rpx;
  247. }
  248. }
  249. .item-border {
  250. border-bottom: 1rpx solid $secondary-text-color;
  251. opacity: 0.22;
  252. }
  253. .item-content {
  254. margin-top: 26.5rpx;
  255. margin-bottom: 57rpx;
  256. .content-row {
  257. display: flex;
  258. align-items: center;
  259. margin-bottom: 25rpx;
  260. .name{
  261. font-size: 30rpx;
  262. color: $primary-text-color;
  263. font-weight: bold;
  264. }
  265. &:last-child {
  266. margin-bottom: 0;
  267. }
  268. &:first-child {
  269. margin-bottom: 37rpx;
  270. }
  271. .label {
  272. font-size: 22rpx;
  273. color: $secondary-text-color;
  274. // width: 200rpx;
  275. margin-right: 19rpx;
  276. flex-shrink: 0;
  277. }
  278. .value {
  279. font-size: 22rpx;
  280. color: $primary-text-color;
  281. margin-right: 40rpx;
  282. }
  283. .project {
  284. // flex: 1;
  285. background: $primary-color;
  286. // border: 1px solid #707070;
  287. border-radius: 11rpx;
  288. color: #fff;
  289. font-size: 22rpx;
  290. padding: 6rpx 12rpx;
  291. }
  292. }
  293. }
  294. .item-actions {
  295. margin-left: -10rpx;
  296. display: flex;
  297. gap: 55rpx;
  298. flex-wrap: wrap;
  299. }
  300. }
  301. }
  302. </style>