index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. <!--
  2. * @Author: liuzhenlin 461480418@qq.ocm
  3. * @Date: 2023-01-12 11:57:48
  4. * @LastEditors: liuzhenlin
  5. * @LastEditTime: 2023-02-17 14:46:41
  6. * @Description: file content
  7. * @FilePath: \oms\pages\project\index.vue
  8. -->
  9. <template>
  10. <view class="home">
  11. <view class="nav">
  12. <view :style="{ paddingTop }">
  13. <view class="title" :style="[{ height }, { lineHeight: height }]">
  14. <view class="back" @click="goBack()">
  15. <u-icon name="arrow-left" color="#ffffff" size="22"></u-icon>
  16. </view>
  17. <text>项目管理</text>
  18. </view>
  19. </view>
  20. </view>
  21. <view class="main">
  22. <!-- 搜索 -->
  23. <view class="query-wrap">
  24. <view class="search-container">
  25. <view class="search-input">
  26. <u-input
  27. clearable
  28. placeholderStyle="font-size:26rpx"
  29. :customStyle="{ height: '66rpx' }"
  30. v-model="queryForm.nboName"
  31. prefixIcon="search"
  32. prefixIconStyle="font-size: 22px;color: #909399"
  33. placeholder="请输入项目名称"
  34. shape="circle"
  35. border="surround"></u-input>
  36. </view>
  37. <view class="search-btn" @click="searchList">搜索</view>
  38. </view>
  39. </view>
  40. <u-tabs
  41. :list="list"
  42. @change="changeTabs"
  43. :current="curTabIndex"
  44. :activeStyle="{
  45. color: '#323232',
  46. fontWeight: 'bold',
  47. }"
  48. :inactiveStyle="{
  49. color: '#969696',
  50. }"></u-tabs>
  51. <u-empty v-if="projectData.length == 0" mode="list" text="暂无数据"></u-empty>
  52. <scroll-view :scroll-y="true" class="data-list" @scrolltolower="lower" v-else>
  53. <view>
  54. <view class="data-item" v-for="(v, i) in projectData" :key="i" @click="toDetails(v)">
  55. <view class="customer-name flex">
  56. <text class="name">{{ v.nboName }}</text>
  57. <view class="user-code">
  58. <text>{{ v.nboCode }}</text>
  59. </view>
  60. </view>
  61. <view class="customer-info flex">
  62. <view class="info-left flex_1">
  63. <view class="info-row flex_l">
  64. <text class="info-label">销售工程师:</text>
  65. <u-text color="#323232" size="24rpx" :text="v.saleName"></u-text>
  66. </view>
  67. <view class="info-row flex_l">
  68. <text class="info-label">客户名称:</text>
  69. <u-text color="#323232" size="24rpx" :text="v.custName"></u-text>
  70. </view>
  71. <view class="info-row flex_l">
  72. <text class="info-label">项目来源:</text>
  73. <u-text
  74. color="#323232"
  75. size="24rpx"
  76. :text="selectDictLabel(sourceOptions, v.nboSource) || '-'"></u-text>
  77. </view>
  78. <view class="info-row flex_l">
  79. <text class="info-label">销售模式:</text>
  80. <u-text
  81. color="#323232"
  82. size="24rpx"
  83. :text="selectDictLabel(salesModelOptions, v.salesModel) || '-'"></u-text>
  84. </view>
  85. <view class="info-row flex_l">
  86. <text class="info-label">产品线:</text>
  87. <u-text
  88. color="#323232"
  89. size="24rpx"
  90. :text="selectDictLabel(productLineOptions, v.productLine) || '-'"></u-text>
  91. </view>
  92. <view class="info-row flex_l">
  93. <text class="info-label">项目预算:</text>
  94. <u-text color="#323232" size="24rpx" :text="formatPrice(v.nboBudget)"></u-text>
  95. </view>
  96. <view class="info-row flex_l">
  97. <text class="info-label">出货金额:</text>
  98. <u-text color="#323232" size="24rpx" :text="formatPrice(v.estTransPrice)"></u-text>
  99. </view>
  100. <view class="flex_l">
  101. <view class="transfer-btn mr20" @click.stop="linkToTransfer(v.id)">
  102. <u-button type="primary" size="small" text="转移项目"></u-button>
  103. </view>
  104. <!-- <view class="transfer-btn mr20" @click.stop="$refs.moveCust.open(v.id)">
  105. <u-button type="primary" size="small" text="移入公海"></u-button>
  106. </view> -->
  107. </view>
  108. </view>
  109. <view class="info-right flex_l flex-column">
  110. <!-- <image class="user-img" src="@/static/images/user.jpg" mode="scaleToFill" /> -->
  111. <u-text color="#646464" size="20rpx" :text="v.salesName"></u-text>
  112. </view>
  113. </view>
  114. </view>
  115. <u-loadmore :status="loadStatus" />
  116. </view>
  117. </scroll-view>
  118. </view>
  119. </view>
  120. </template>
  121. <script>
  122. import projectApi from '../../api/project'
  123. import to from 'await-to-js'
  124. export default {
  125. name: 'omsIndex',
  126. components: {},
  127. data() {
  128. return {
  129. list: [
  130. {
  131. name: '全部项目',
  132. status: 0,
  133. nboType: null,
  134. },
  135. {
  136. name: 'C类项目',
  137. status: 1,
  138. nboType: '30',
  139. },
  140. {
  141. name: 'B类项目',
  142. status: 2,
  143. nboType: '20',
  144. },
  145. {
  146. name: 'A类项目',
  147. status: 3,
  148. nboType: '10',
  149. },
  150. {
  151. name: '成交项目',
  152. status: 4,
  153. nboType: '40',
  154. },
  155. {
  156. name: '储备项目',
  157. status: 5,
  158. nboType: '50',
  159. },
  160. ],
  161. curTabIndex: 0, //tabs状态
  162. height: '',
  163. paddingTop: '',
  164. queryForm: {
  165. pageNum: 0,
  166. pageSize: 10,
  167. nboName: '', //项目名称
  168. },
  169. projectData: [], //项目列表
  170. projectDataTotal: 0, //列表元素数量
  171. loadStatus: '', //加载状态
  172. salesModelOptions: [], //销售模式列表
  173. productLineOptions: [], //产品线列表
  174. sourceOptions: [], //来源列表
  175. }
  176. },
  177. created() {
  178. const navData = uni.getMenuButtonBoundingClientRect()
  179. this.height = navData.height + 'px'
  180. this.paddingTop = navData.top + 'px'
  181. },
  182. onShow() {
  183. this.getOptions()
  184. this.searchList()
  185. },
  186. methods: {
  187. getOptions() {
  188. Promise.all([
  189. this.getDicts('proj_sales_model'),
  190. this.getDicts('sys_product_line'),
  191. this.getDicts('proj_nbo_source'),
  192. ])
  193. .then(([model, line, source]) => {
  194. this.salesModelOptions = model.data.values || []
  195. this.productLineOptions = line.data.values || []
  196. this.sourceOptions = source.data.values || []
  197. })
  198. .catch((err) => console.log(err))
  199. },
  200. // 改变tab
  201. changeTabs(data) {
  202. console.log(data)
  203. this.curTabIndex = data.status
  204. this.searchList()
  205. },
  206. // 上拉滚动
  207. lower() {
  208. if (this.projectData.length < this.projectDataTotal && this.loadStatus != 'loading') {
  209. this.$u.throttle(this.getProjectData(), 2000, false)
  210. }
  211. },
  212. // 查询列表
  213. searchList() {
  214. this.queryForm.pageNum = 0
  215. this.getProjectData(true)
  216. },
  217. async getProjectData(reset) {
  218. this.loadStatus = 'loading'
  219. this.queryForm.pageNum++
  220. let params = {
  221. nboType: this.list[this.curTabIndex].nboType,
  222. nboName: this.queryForm.nboName,
  223. pageNum: this.queryForm.pageNum,
  224. pageSize: this.queryForm.pageSize,
  225. }
  226. const [err, res] = await to(projectApi.getList(params))
  227. if (err) {
  228. this.loadStatus = 'nomore'
  229. return
  230. }
  231. if (res && res.code == 200) {
  232. if (reset) {
  233. this.projectData = res.data.list || []
  234. } else {
  235. this.projectData = [...this.projectData, ...(res.data.list || [])]
  236. }
  237. this.projectDataTotal = res.data.total
  238. console.log(
  239. 'this.projectData.length == this.projectDataTotal',
  240. this.projectData.length == this.projectDataTotal
  241. )
  242. this.loadStatus = this.projectData.length == this.projectDataTotal ? 'nomore' : 'loadmore'
  243. } else {
  244. this.loadStatus = 'nomore'
  245. }
  246. },
  247. // 跳转到转移客户
  248. linkToTransfer(id) {
  249. uni.navigateTo({
  250. //保留当前页面,跳转到应用内的某个页面
  251. url: '/pages/project/transfer?id=' + id,
  252. })
  253. },
  254. goBack() {
  255. uni.navigateBack({
  256. //关闭当前页面,返回上一页面或多级页面。
  257. delta: 1,
  258. })
  259. },
  260. toDetails(v) {
  261. uni.navigateTo({
  262. //保留当前页面,跳转到应用内的某个页面
  263. url: '/pages/project/details?id=' + v.id,
  264. })
  265. },
  266. },
  267. }
  268. </script>
  269. <style>
  270. page {
  271. background: #f2f3f5;
  272. }
  273. </style>
  274. <style lang="scss" scoped>
  275. .home {
  276. padding-top: 188rpx;
  277. .nav {
  278. position: absolute;
  279. left: 0;
  280. top: 0;
  281. width: 100%;
  282. height: 284rpx;
  283. background: #3e7ef8;
  284. .title {
  285. position: relative;
  286. text-align: center;
  287. font-size: 32rpx;
  288. font-weight: bold;
  289. color: #ffffff;
  290. .back {
  291. position: absolute;
  292. top: 0;
  293. bottom: 0;
  294. margin: auto;
  295. left: 70rpx;
  296. display: flex;
  297. }
  298. }
  299. }
  300. .main {
  301. position: absolute;
  302. width: 100%;
  303. height: calc(100vh - 188rpx);
  304. background: #ffffff;
  305. box-shadow: 0 6rpx 19rpx 2rpx rgba(0, 45, 132, 0.15);
  306. border-radius: 31rpx 31rpx 0 0;
  307. padding: 0 32rpx;
  308. overflow: auto;
  309. padding-bottom: 64rpx;
  310. .query-wrap {
  311. padding-top: 20rpx;
  312. .search-container {
  313. display: flex;
  314. align-items: center;
  315. .search-input {
  316. flex: 1;
  317. }
  318. .search-btn {
  319. text-align: center;
  320. line-height: 60rpx;
  321. border-radius: 12rpx;
  322. width: 100rpx;
  323. height: 60rpx;
  324. font-size: 26rpx;
  325. margin: 0 0 0 12rpx;
  326. background: $u-primary;
  327. color: #ffffff;
  328. }
  329. }
  330. }
  331. .data-list {
  332. width: 100%;
  333. height: calc(100vh - 422rpx);
  334. overflow: auto;
  335. .data-item {
  336. background: rgba(242, 243, 245, 0.5);
  337. border-radius: 15rpx;
  338. padding: 28rpx 40rpx 28rpx 38rpx;
  339. margin-top: 32rpx;
  340. .customer-name {
  341. .name {
  342. flex: 1;
  343. color: #323232;
  344. font-weight: bold;
  345. font-size: 28rpx;
  346. margin-right: 12rpx;
  347. }
  348. .user-code {
  349. width: 180rpx;
  350. height: 32rpx;
  351. font-size: 24rpx;
  352. color: #323232;
  353. line-height: 32rpx;
  354. }
  355. }
  356. .customer-info {
  357. .info-left {
  358. .transfer-btn {
  359. margin-top: 20rpx;
  360. width: 150rpx;
  361. }
  362. .info-row {
  363. margin-top: 12rpx;
  364. .info-label {
  365. color: #646464;
  366. font-size: 24rpx;
  367. }
  368. }
  369. }
  370. .info-right {
  371. padding-top: 30rpx;
  372. .user-img {
  373. border-radius: 50%;
  374. width: 46rpx;
  375. height: 46rpx;
  376. }
  377. }
  378. }
  379. }
  380. }
  381. }
  382. .filter-popup {
  383. background: rgba(0, 0, 0, 0.8);
  384. position: fixed;
  385. width: 100%;
  386. height: 100%;
  387. left: 0;
  388. z-index: 1;
  389. .filter-wrap {
  390. width: 100%;
  391. padding: 20rpx;
  392. background: #ffffff;
  393. .filter-item {
  394. padding-bottom: 30rpx;
  395. .tit {
  396. font-size: 26rpx;
  397. color: #323232;
  398. font-weight: bold;
  399. padding-bottom: 20rpx;
  400. }
  401. .menu-list {
  402. display: flex;
  403. flex-wrap: wrap;
  404. .menu-item {
  405. margin-right: 40rpx;
  406. margin-bottom: 20rpx;
  407. }
  408. }
  409. }
  410. }
  411. .btn-box {
  412. width: 698rpx;
  413. height: 75px;
  414. display: flex;
  415. align-items: center;
  416. justify-content: space-between;
  417. > view {
  418. width: 320rpx;
  419. height: 40px;
  420. border-radius: 40px;
  421. border: solid 1rpx #ec652b;
  422. align-items: center;
  423. justify-content: center;
  424. text-align: center;
  425. line-height: 40px;
  426. }
  427. .reset {
  428. color: #ec652b;
  429. }
  430. .submit {
  431. color: #fff;
  432. background-color: #ec652b;
  433. }
  434. }
  435. }
  436. }
  437. </style>